2016年7月25日12:34:05 常见的括号有三种{},[],(),例如{[()()]},当计算机接受到第一个{时,计算机最迫切见到的是},不幸运的是 接下来它见到的是[,因此当前它想见到]比}还要迫切,更不幸运的是接下来它见到了(,这时它想见到)比]更为迫切 这时来了),这时它会将(从表中删除,当前期望的是],但是接下来来到的是(,因此最期望的括号成为),)比[更为迫切, 接下来它就遇到了),这时最受期望的被盼到了,此时它最期望的是],其次是},于是接下来它遇到了]和} 表达式的括号是否匹配问题: 输入:由用户指定一个包含括号的表达式,那么这个表达式如何存贮呢? 可以考虑顺序的存贮结构,但是之前并不知道该表达式包含多少个字符(括号,数字以及运算符), 因此使用链式存贮结构较为合理;
处理:总结:括号的匹配问题符合栈的先进后出的特点,因此解决这个问题可以设置一个栈来判断表达式的括号是否是匹配的 1.遇到的是左括号,直接进栈,当前最期盼的是右括号,接下来继续读取接下里表达式的字符;
2.遇到的是右括号,与栈顶的左括号进行匹配,如果是匹配的,则将栈顶元素出栈,同时继续读取下一个表达式字符;
注意:这个操作的前提是栈中至少一个元素,即至少有一个左括号,当这个条件不满足的时候,即栈为空,这时说明这个表达 式中缺少左括号, 3.遇到的是数字和运算符,则应该不进行任何的操作,直接继续读取接下来的表达式字符;
输出:该表达式中的括号是否匹配,给出确切的结果;
当用户输入的字符序列读取完毕时,这时若栈为空,说明表达式是匹配的,否则不匹配
总结:指针重要性: 1.很多复杂的数据结构必须使用指针来体现 2.指针可以访问硬件 3.指针可以使函数返回一个以上的返回值 4.指针可以快速的传递数据:(1)耗用内存空间小(2)传递数据速度快 5.指针是C语言的灵魂;
在使用指针进行函数参数的传递的时候;很多时候我们会疑惑是传递地址,还是传递数据;
通过本程序可以总结一点是:凡是需要修改指针变量所指向的变量时,这时使用函数进行参数的传递时候,必须传递所需要修改变量的 地址,如果不传递地址,会使只是在函数中使用参数建立了实参的副本,实际上他们属于不同的=内存空间,而在函数调用的时候参数通 常是静态变量,当函数运行时,系统会将函数以及它的所有局部变量压栈,在函数运行结束后,函数弹栈,所有局部变量出栈释放,而无法 更改内存中另一块区域变量的值;
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef char DataType;
//存贮用户输入表达式字符序列的链表结构体
typedef struct node
{
DataType ch;
struct node * pNext;
}linkList;
//函数前置声明
linkList * createLinkList(linkList * pHead);//创建单链表
void initLinkList(linkList ** pHead);//初始化单链表
void traverseLinkList(linkList * pHead);//遍历单链表
void initListStack(linkList ** pTop);//初始化链栈
int dealInfor(linkList * pHead);//信息处理函数
int isEmpty(linkList * pTop);//判断链式栈是否为空
int getTop(linkList * pTop,DataType * element);//获取栈顶元素
int pushStack(linkList ** pTop,DataType element);//压栈
int popStack(linkList ** pTop,DataType * element);//出栈
int isMatch(DataType ch1,DataType ch2);//括号匹配判断
//初始化链表
void initLinkList(linkList ** pHead)
{
*pHead = (linkList * )malloc(sizeof(linkList));
if(NULL == *pHead)
{
printf("动态内存分配失败!\n");
exit(-1);
}
(*pHead)->pNext = NULL;
return;
}
//初始化链式栈
void initListStack(linkList ** pTop)
{
*pTop = NULL;
return ;
}
//判断链式栈是否为空
int isEmpty(linkList * pTop)
{
if(NULL == pTop)
{
return 1;
}
else
{
return 0;
}
}
//创建一个单链表
linkList * createLinkList(linkList * pHead)
{
linkList * pNew ;
linkList * pTail;
char c;
pTail = pHead;
pHead->ch = '0';
while( '\n' != (c=getchar()) )
{
pNew = (linkList * )malloc(sizeof(linkList));
if(NULL == pNew)
{
printf("动态内存分配失败!\n");
exit(-1);
}
pNew->ch = c;
/*if(NULL == pHead->pNext) { pNew->pNext = NULL; pTail->pNext = pNew; pTail = pNew; } else { pNew->pNext = NULL; pTail->pNext = pNew; pTail = pNew; } */
pNew->pNext = NULL;
pTail->pNext = pNew ;
pTail = pNew;
pHead->ch++;
}
return pHead;
}
//遍历输出单链表
void traverseLinkList(linkList * pHead)
{
linkList * pCur;
pCur = pHead->pNext;
while(NULL != pCur)
{
printf("%c",pCur->ch);
pCur = pCur->pNext;
}
printf("\n");
return;
}
//判断用户所输入的表达式括号是否匹配
int dealInfor(linkList * pHead,linkList * pTop)
{
linkList * pCur;
DataType element;
pCur = pHead->pNext;
while(NULL != pCur)
{
printf(">计算机遇到%c\n",pCur->ch);
switch(pCur->ch)
{
//如果是左括号类型的字符,直接将该字符压栈
case '(':
case '{':
case '[':pushStack(&pTop,pCur->ch);
printf(" 【进栈】的元素为:【%c】\n",pCur->ch);
pCur = pCur->pNext;
break;
//如果是右括号类型的字符,则进行匹配比较
case ')':
case '}':
case ']':if(isEmpty(pTop))
{
printf("该表达式缺少左括号!\n");
return 0;
}
else
{
getTop(pTop,&element);
if(isMatch(element,pCur->ch))
{
popStack(&pTop,&element);
printf("[出栈]的元素为:[%c]\n",element);
pCur = pCur->pNext;
}
else
{
return 0;
}
}
break;
default :pCur = pCur->pNext;
}
}
//如果表达式序列被读取完,同时栈为空,说明匹配,否则不匹配
if(isEmpty(pTop))
return 1;
else
return 0;
}
//链式栈压栈操作
int pushStack(linkList ** pTop, DataType element)
{
linkList * pNew ;
pNew = (linkList * )malloc(sizeof(linkList));
if(NULL == pNew)
{
printf("动态内存分配失败!\n");
exit(-1);
}
pNew->ch = element;
/*if(pTop == NULL) { pNew->pNext = NULL; pTop = pNew; } else { pNew->pNext = pTop; pTop = pNew; }*/
pNew->pNext = *pTop;
*pTop = pNew;
return 1;
}
//获取栈顶元素
int getTop(linkList * pTop, DataType * element)
{
if(isEmpty(pTop))
return 0;
*element = pTop->ch;
return 1;
}
//链式栈的出栈操作
int popStack(linkList ** pTop,DataType * element)
{
linkList * pFree;
if(isEmpty(*pTop))
return 0;
pFree = *pTop;
*element = (*pTop)->ch;
*pTop = (*pTop)->pNext;
free(pFree);
return 1;
}
//判断括号是否匹配,匹配返回1,不匹配返回0
int isMatch(DataType ch1,DataType ch2)
{
if(ch1=='('&&ch2==')')
return 1;
else if(ch1=='['&&ch2==']')
return 1;
else if(ch1=='{'&&ch2=='}')
return 1;
else
return 0;
}
//主函数
int main(void)
{
DataType ch1[MAXSIZE];
linkList * pHead;
linkList * pTop;
int i;
char ch;
initLinkList(&pHead);
initListStack(&pTop);
printf("请输入一个表达式:");
pHead = createLinkList(pHead);
printf("您所输入的表达式:");
traverseLinkList(pHead);
if(dealInfor(pHead,pTop))
{
printf("表达式的括号匹配!\n");
}
else
{
printf("表达式的括号不匹配!\n");
}
return 0;
}