C语言实现括号匹配,中缀表达式转后缀表达式并计算具体代码实现
2017-11-17 10:31
956 查看
1.在本项目拟采用顺序栈来实现。
顺序栈的存储定义
(1)初始化栈
算法描述:初始化空栈,包括顺序栈存储单元的分配等。
(2)出栈
算法描述:如果栈不空,则将栈顶的元素出栈。
(3)入栈
算法描述:如果栈没满,则添加新元素进栈,作为新的栈顶元素。
(4)取栈顶元素
算法描述:当栈非空时,对栈进行访问,返回此时栈顶元素的值,不改变栈中元素。
(5)括号匹配算法
算法描述:检查字符串中的括号是否匹配,可以借助栈实现。自左至右扫描字符串,当遇到左括号时,执行入栈操作。当遇到右括号时,与栈顶符号进行匹配,若匹配成功,则执行一次出栈,否则,直接断定匹配失败。如果字符串访问结束时,栈空,则说明匹配成功,否则匹配失败。
(6)转换后缀表达式算法
算法描述:将中缀表达式转换为后缀表达式。详细的描述请参照我之前一篇算法描述的文章。
(7)后缀表达式的计算
算法描述:对转换得到的后缀表达式进行计算。详细描述请参照我之前一篇算法描述的文章。
具体项目实现
运行主界面:
运行测试,如图所示。分三种情况进行测试:一是不包含小括号的表达式、二是包含小括号并且匹配成功、三是包含小括号但匹配失败。
退出环节设计运行,如图所示。
顺序栈的存储定义
typedef struct stack { SElemType *base;//栈底指针 SElemType *top;//栈顶指针 int stacksize;//栈分配的存储空间大小 }SqStack;2.主要功能函数设计及算法描述
(1)初始化栈
算法描述:初始化空栈,包括顺序栈存储单元的分配等。
void InitStack(SqStack s) { s.base=s.top=( SElemType *)malloc(MAXSIZE*sizeof(SElemType)); if(s.base==NULL) exit(-2); s.stacksize=MAXSIZE; }
(2)出栈
算法描述:如果栈不空,则将栈顶的元素出栈。
Status Pop(SqStack s,SElemType e) {if(s.top==s.base) return ERROR; s.top--; e=*s.top; return OK; }
(3)入栈
算法描述:如果栈没满,则添加新元素进栈,作为新的栈顶元素。
Status Push(SqStack s,SElemType e) {if(s.top-s.base==s.stacksize) return ERROR; *s.top=e; s.top++; return ok; }
(4)取栈顶元素
算法描述:当栈非空时,对栈进行访问,返回此时栈顶元素的值,不改变栈中元素。
SElemType GetTop(SqStack s) {if(s.top!=s.base) return *(s.top-1); }
(5)括号匹配算法
算法描述:检查字符串中的括号是否匹配,可以借助栈实现。自左至右扫描字符串,当遇到左括号时,执行入栈操作。当遇到右括号时,与栈顶符号进行匹配,若匹配成功,则执行一次出栈,否则,直接断定匹配失败。如果字符串访问结束时,栈空,则说明匹配成功,否则匹配失败。
int Match(SqStack s ,char *p) {//检查表达式中小括号是否匹配 flag=0; while(*p!='\0') { if(*p== '(' ) { if(s.top-s.base ==s.stacksize) exit(-1); else Push(s,*p);//将所有的左括号入栈 } if(*p== ')' ) { if(s.top!=s.base&&GetTop(s)=='(') { Pop(s); flag=1; } else flag=2;} p++; }//while if((flag==1||flag==0)&&s.top==s.base) return 1; else if(flag==2) return 0;} }//Match
(6)转换后缀表达式算法
算法描述:将中缀表达式转换为后缀表达式。详细的描述请参照我之前一篇算法描述的文章。
void trans(SElemType str[],SElemType rpn[]) { i=0,t=0; ch=str[i++]; while(ch!='\0') { switch(ch) { case '(': Push(op,ch); break; case ')': while(GetTop(op)!='(' ) { rpn[t]= GetTop(op); Pop(op); t++; } op.top--;//此处必须再次进行--运算,才能忽略已经进入的‘(’ break; case '+': case '-': while(op.top!=op.base && GetTop(op)!='(' ) {rpn[t]= GetTop(op); Pop(op); t++; } Push(op.ch); break; case '*': case '/': while(GetTop(op)'*'|| GetTop(op)=='/') {rpn[t]= GetTop(op); Pop(op); t++; } Push(op.ch); break; case ' ':break; default: while(ch>='0'&&ch<='9') {rpn[t]=ch; t++; ch=str[i]; i++; } i--; rpn[t]='#';t++; }//switch ch=str[i]; i++; }//while while(op.top!=op.base) {rpn[t]= GetTop(op); t++; Pop(op); }//while rpn[t]='\0'; }//trans
(7)后缀表达式的计算
算法描述:对转换得到的后缀表达式进行计算。详细描述请参照我之前一篇算法描述的文章。
int value(char rpn[]) { t=0, ch=rpn[t], t++; while(ch!='\0') { switch(ch) {case '+': m=Pop(st);n=Pop(st); Push(st,n+m); break; case '-': m=Pop(st);n=Pop(st); Push(st,n-m); break; case '*': m=Pop(st);n=Pop(st); Push(st,n*m); break; case '/': if(GetTop(st)!=0) {m=Pop(st);n=Pop(st); Push(st,n/m); break;} else {printf("\n除0错误!\n"); exit(0); } default: d=0; while(ch>='0'&&ch<='9') {d=10*d+ch-'0'; ch=rpn[t]; t++; } Push(st,d); }//switch ch=rpn[t]; t++; }//while return GetTop(st); }//value
具体项目实现
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #define MAXSIZE 100 //此程序中存储单元采用malloc( )函数分配,但没有涉及处理溢出的问题,相关涉及可以参//照realloc( )的使用方法 //顺序栈的存储定义 typedef struct stack { char *base;//栈底指针 char *top;//栈顶指针 int stacksize;//栈分配的存储空间大小 }SqStack; SqStack op,st;//顺序栈op用来存储运算符,st用来存放数值 void Menu(); void InitStack(); void trans(char str[],char rpn[]); int value(char rpn[]); int Match(char *p); //***************************************************************************** void Menu() {//界面函数 printf("*********表达式求值(只能包含+、-、*、/、()和正整数)********* ******\n"); printf("请选择:1.输入表达式 2.括号匹配检查 3.转换后缀表达式 4.表达式计算5.退出\n"); } //***************************************************************************** void InitStack() {//初始化栈op、st op.base=op.top=(char *)malloc(MAXSIZE*sizeof(char)); if(op.base==NULL) exit(-2); st.base=st.top=(char *)malloc(MAXSIZE*sizeof(char)); if(st.base==NULL) exit(-2); op.stacksize=op.stacksize=MAXSIZE; } //***************************************************************************** int Match(char *p) {//检查表达式中小括号是否匹配 int flag=0; SqStack s; s.base=s.top=(char*)malloc(MAXSIZE*sizeof(char)); if(!s.base) exit(-2); s.stacksize=MAXSIZE; while(*p!='\0') { if(*p== '(') { if(s.top-s.base ==s.stacksize) exit(-1); else {*s.top=*p; s.top++;//将所有的左括号入栈 } } if(*p== ')') { if(s.top!=s.base&&*(s.top-1)=='(') { s.top--; flag=1; } else flag=2;} p++; }//while if((flag==1||flag==0)&&s.top==s.base) {s.top=s.base;//将栈清空 return 1;} else if(flag==2) {s.top=s.base;//将栈清空 return 0;} }//Match //***************************************************************************** void trans(char str[],char rpn[]) {//将中缀表达式转换为后缀表达式 char ch; int i=0,t=0; ch=str[i]; i++; while(ch!='\0') { switch(ch) { case '(': *op.top++=ch; break; case ')': while(*(op.top-1)!='(') { rpn[t]=*(op.top-1); op.top--; t++; } op.top--;//此处必须再次进行--运算,才能忽略已经进入的‘(’ break; case '+': case '-': while(op.top!=op.base && *(op.top-1)!='(') {rpn[t]=*(op.top-1); op.top--; t++; } *op.top++=ch; break; case '*': case '/': while(*(op.top-1)=='*'||*(op.top-1)=='/') {rpn[t]=*(op.top-1); op.top--; t++; } *op.top++=ch; break; case ' ':break; default: while(ch>='0'&&ch<='9') {rpn[t]=ch; t++; ch=str[i]; i++; } i--; rpn[t]='#';t++; }//switch ch=str[i]; i++; }//while while(op.top!=op.base) {rpn[t]=*(op.top-1); t++; op.top--; }//while rpn[t]='\0'; }//trans //***************************************************************************** int value(char rpn[]) {//后缀表达式求值 float d; char ch; int t=0; ch=rpn[t]; t++; while(ch!='\0') { switch(ch) {case '+': *(st.top-2)=*(st.top-2) + *(st.top-1); st.top--; break; case '-': *(st.top-2)=*(st.top-2) - *(st.top-1); st.top--; break; case '*': *(st.top-2)=*(st.top-2) * *(st.top-1); st.top--; break; case '/': if(*(st.top-1)!=0) *(st.top-2)=*(st.top-2) / *(st.top-1); else {printf("\n除0错误!\n"); exit(0); } st.top--; break; default: d=0; while(ch>='0'&&ch<='9') {d=10*d+ch-'0'; ch=rpn[t]; t++; } *(st.top++)=d; }//switch ch=rpn[t]; t++; }//while return *(st.top-1); }//value //***************************************************************************** int main() {//主函数 char str[MAXSIZE],rpn[MAXSIZE],g,f; //str数组用来存储接收到的字符串,rpn用来存放转换出来的后缀表达式 int i,j=0; InitStack(); Menu(); while(1) { scanf("%d",&g); switch(g) { case 1: printf("请输入表达式:"); scanf("%s",str); i=Match(str); break; case 2: if(i==1) printf("匹配成功!\n"); else printf("匹配失败!\n"); break; case 3: if(i==1) {trans(str,rpn); printf("后缀表达式为:%s\n", rpn); j=1;} else {j=0; printf("表达式中括号匹配错误!\n");} break; case 4: if(j) printf("计算结果为:%d\n",value(rpn)); else printf("后缀表达式转换遇到问题!\n"); break; case 5: printf("确定要退出系统吗?(y/n)\n"); getchar();f=getchar(); if(f=='y'||f=='Y') exit(0); else {printf("请重新选择!\n");break;} default:printf("输入错误!\n"); exit(1); }//switch }//while return 0; }//main
项目运行与测试
编译运行后显示结果为:运行主界面:
运行首界面 |
运行测试,如图所示。分三种情况进行测试:一是不包含小括号的表达式、二是包含小括号并且匹配成功、三是包含小括号但匹配失败。
运行测试 |
退出环节设计运行,如图所示。
退出设计 |
相关文章推荐
- C语言实现括号匹配,中缀表达式转后缀表达式并计算的算法
- [置顶] 中缀表达式转成后缀表达式(含java实现的具体代码)
- "括号匹配, 中缀表达式转化为后缀表示式, 计算中缀表达式, 计算后缀表达式"完整代码
- (1.2.2.1)栈和队列的应用:数制转换、括号匹配、后缀表达式求解,中缀表达式求解、双栈实现队列,min函数栈
- 数据结构实现中缀表达式到后缀表达式,再到计算出结果的代码
- 数据结构—中缀表达式转后缀表达式算法及实现—栈的应用—计算表达式(C++代码实现)(1)
- java实现中缀表达式转后缀表达式并且计算
- java实现中缀表达式转后缀表达式并且计算
- 中缀表达式转后缀表达式--C# 代码实现
- Java实现中缀表达式转后缀表达式并计算结果
- 后缀表达式计算的代码实现
- 堆栈实现中缀表达式转后缀表达式及计算表达式的值
- java实现中缀表达式转后缀表达式并且计算
- java实现中缀表达式转后缀表达式并且计算
- 【数据结构】用栈实现的简单计算器(先转换为后缀表达式、可以计算带括号的)
- C语言 实现中缀表达式转后缀表达式并求值
- 中缀表达式转后缀表达式与括号匹配
- Java栈实现括号匹配、中序转后序表达式、中序表达式直接计算
- 栈 实现 中缀表达式 转换成 后缀表达式 并 计算
- 中缀表达式转换为后缀表达式 简易实现(c++)(简易表达式计算)