数据结构之利用栈实现四则运算
2018-01-17 09:18
183 查看
本文解决的问题:
9. 使用堆栈功能实现字符串表达式的求值。(表达式指四则运算表达式)
本文利用的求解方法是:
(1)、将表达式转化成后缀表达式;
(2)、利用后缀表达式结合栈求结果。
而关于中缀、前缀、后缀表达式的理论以及相互转化的步骤,我之前参考了一篇博文,觉得还不错,给大家分享一下:前、后、中缀表达式
实现代码如下:
-----------------------------------------------------------------------------------------------------------------
2018年1月18日更新,增加了对括号的识别
如有疑问,请及时提出,谢谢!!
9. 使用堆栈功能实现字符串表达式的求值。(表达式指四则运算表达式)
本文利用的求解方法是:
(1)、将表达式转化成后缀表达式;
(2)、利用后缀表达式结合栈求结果。
而关于中缀、前缀、后缀表达式的理论以及相互转化的步骤,我之前参考了一篇博文,觉得还不错,给大家分享一下:前、后、中缀表达式
实现代码如下:
/*******************************9、使用堆栈功能实现字符串表达式的求值*************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> const int StackSize=100;//栈空间 typedef struct Stack { char data[StackSize]; int top; }Stack; void initStack(Stack *s) { s->top=-1; } //匹配运算符 int mateChar(char s) { int i; switch(s){ case '+':i=0;break; case '-':i=1;break; case '*':i=2;break; case '/':i=3;break; case '(':i=4;break; case ')':i=5;break; } return i; } //入栈 void push(char x,Stack *s) { if(s->top>=100) { printf("栈满!!\n"); }else{ s->top++; s->data[s->top] = x; } } //出栈 char pop(Stack *s) { char x; if(s->top==-1){ printf("栈为空!!\n"); return '#'; }else{ x=s->data[s->top]; s->top--; } return x; } //取运算符栈顶元素 char get_char(Stack *s) { char x; if(s->top==-1){ //printf("栈为空!!\n"); return '#'; }else{ x=s->data[s->top]; } return x; } //字符串数字转成数字 int tranform_num(char x) { int i; i=x-'0'; return i; } //数字转字符串 char tranfoe_char(int x) { char s; s=x+'0'; return s; } //输出栈内元素 void printf_stack(Stack *s) { if(s->top == -1){ printf("栈内无元素!!\n"); }else{ int temp=0; while(temp<=s->top) { printf("%c",s->data[temp]); temp++; } printf("\n"); } } int calculate(int x,int y,char s) { int i; switch(s){ case '+':i=x+y;break; case '-':i=x-y;break; case '*':i=x*y;break; case '/':i=x/y;break; } return i; } //根据后缀表达式计算结果 int count(Stack *s,Stack *t) { int temp=0; char count; //遍历存储后缀表达式的栈 while(temp<=s->top){ //获得栈顶元素 char k=s->data[temp]; if(k>='0'&&k<='9') { //如果是数字,进t栈 push(k,t); }else{ //如果是操作符,则计算 int x=tranform_num(pop(t)); int y=tranform_num(pop(t)); int z=calculate(x,y,k); push(tranfoe_char(z),t); } temp++; } count=t->data[t->top]; return tranform_num(count); } int main() { Stack s1,s2;//s1存运算符 4000 ,s2存最后结果 char nums[100]; int i; int length; char *p=nums; int prior[4][4]={{0,0,1,1},{0,0,1,1},{0,0,0,0},{0,0,0,0}}; //初始化 initStack(&s1); initStack(&s2); printf("请输入运算式,运算数为0-9:\n"); scanf("%s",&nums); printf("您输入的是:%s\n",nums); length=(int)strlen(nums); /*************************************************转成后缀表达式********************************/ //1、循环表达式 ,确定入栈和出栈 for(i=0;i<length;i++) { //数字 if(*(p+i)>='0'&&*(p+i)<='9') { push(*(p+i),&s2); }else{//运算符 int m;//当前运算符位置 int n;//栈顶元素运算符位置 char k=get_char(&s1); if(k == '#') { //栈内为空,直接入栈 push(*(p+i),&s1); }else{ //栈内不为空,比较优先级 m=mateChar(*(p+i)); n=mateChar(k); if(prior [m] == 1){ //新运算符优先级大于栈顶运算符,直接插入s1 push(*(p+i),&s1); }else if(prior [m] == 0) { //新运算符优先级不大于栈顶运算符,将s1栈顶元素弹出,压入s2,继续比较新运算符和s1栈顶的优先级 char temp=pop(&s1); push(temp,&s2); if(k=get_char(&s1) == '#') { push(*(p+i),&s1); continue; }else{ while(prior [m] == 0) { char temp=pop(&s1); push(temp,&s2); k=get_char(&s1); n=mateChar(k); } } /* char temp=pop(&s1); push(temp,&s2); k=get_char(&s1); while(k != '#') { n=mateChar(k); if(prior[m] == 0){ char temp=pop(&s1); push(temp,&s2); k=get_char(&s1); }else{ push(*(p+i),&s1); break; } } */ } } } } char k=get_char(&s1); while(k != '#'){ pop(&s1); push(k,&s2); k=get_char(&s1); } printf("此时后缀表达式为:\n"); printf_stack(&s2); /*************************************************运用后缀表达式求结果********************************/ int count_=count(&s2,&s1); printf("结果为:%d\n",count_); return 0; }
-----------------------------------------------------------------------------------------------------------------
2018年1月18日更新,增加了对括号的识别
/*******************************9、使用堆栈功能实现字符串表达式的求值(括号和多位数)*************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> const int StackSize=100;//栈空间 typedef struct Stack { char data[StackSize]; int top; }Stack; void initStack(Stack *s) { s->top=-1; } //匹配运算符 int mateChar(char s) { int i; switch(s){ case '+':i=0;break; case '-':i=1;break; case '*':i=2;break; case '/':i=3;break; case '(':i=4;break; case ')':i=5;break; } return i; } //入栈 void push(char x,Stack *s) { if(s->top>=100) { printf("栈满!!\n"); }else{ s->top++; s->data[s->top] = x; } } //出栈 char pop(Stack *s) { char x; if(s->top==-1){ printf("栈为空!!\n"); return '#'; }else{ x=s->data[s->top]; s->top--; } return x; } //取运算符栈顶元素 char get_char(Stack *s) { char x; if(s->top==-1){ //printf("栈为空!!\n"); return '#'; }else{ x=s->data[s->top]; } return x; } //字符串数字转成数字 int tranform_num(char x) { int i; i=x-'0'; return i; } //数字转字符串 char tranfoe_char(int x) { char s; s=x+'0'; return s; } //输出栈内元素 void printf_stack(Stack *s) { if(s->top == -1){ printf("栈内无元素!!\n"); }else{ int temp=0; while(temp<=s->top) { printf("%c",s->data[temp]); temp++; } printf("\n"); } } int calculate(int x,int y,char s) { int i; switch(s){ case '+':i=x+y;break; case '-':i=x-y;break; case '*':i=x*y;break; case '/':i=x/y;break; } return i; } //根据后缀表达式计算结果 int count(Stack *s,Stack *t) { int temp=0; char count; //遍历存储后缀表达式的栈 while(temp<=s->top){ //获得栈顶元素 char k=s->data[temp]; if(k>='0'&&k<='9') { //如果是数字,进t栈 push(k,t); }else{ //如果是操作符,则计算 int x=tranform_num(pop(t)); int y=tranform_num(pop(t)); int z=calculate(x,y,k); push(tranfoe_char(z),t); } temp++; } count=t->data[t->top]; return tranform_num(count); } int main() { Stack s1,s2;//s1存运算符,s2存最后结果 char nums[100]; int i; int length; char *p=nums; int prior[4][4]={{0,0,0,0},{0,0,0,0},{1,1,0,0},{1,1,0,0}}; //初始化 initStack(&s1); initStack(&s2); printf("请输入运算式(要求:不包含括号,数字范围为0-9):\n"); scanf("%s",&nums); //printf("您输入的是:%s\n",nums); length=(int)strlen(nums); /*************************************************转成后缀表达式********************************/ //1、循环表达式 ,确定入栈和出栈 for(i=0;i<length;i++) { //数字 if(*(p+i)>='0'&&*(p+i)<='9') { push(*(p+i),&s2); }else{//运算符 int m;//当前运算符位置 int n;//栈顶元素运算符位置 char k=get_char(&s1); if(k == '#') { //栈内为空,直接入栈 push(*(p+i),&s1); }else{ //栈内不为空,比较优先级 m=mateChar(*(p+i)); n=mateChar(k); if(m == 4 || n == 4) { //若入栈的为(或者栈顶为(,则元素直接进栈; push(*(p+i),&s1); }else if(m == 5){ //如果入栈元素为),则将符号栈内(之前的符号依次出栈,放入数字栈中 char temp1=pop(&s1); while(temp1 != '(') { push(temp1,&s2); temp1=pop(&s1); } }else if(prior[m] == 1){ //新运算符优先级大于栈顶运算符,直接插入s1 push(*(p+i),&s1); }else if(prior[m] == 0) { //新运算符优先级不大于栈顶运算符,将s1栈顶元素弹出,压入s2,继续比较新运算符和s1栈顶的优先级 char temp=pop(&s1); push(temp,&s2); if(k=get_char(&s1) == '#') { push(*(p+i),&s1); continue; }else{ temp=pop(&s1); n=mateChar(temp); while(prior[m] == 0) { push(temp,&s2); k=get_char(&s1); if(k == '#') { break; } n=mateChar(k); } push(*(p+i),&s1); } /* char temp=pop(&s1); push(temp,&s2); k=get_char(&s1); while(k != '#') { n=mateChar(k); if(prior[m] == 0){ char temp=pop(&s1); push(temp,&s2); k=get_char(&s1); }else{ push(*(p+i),&s1); break; } } */ } } } } char k=get_char(&s1); while(k != '#'){ pop(&s1); push(k,&s2); k=get_char(&s1); } printf("此时后缀表达式为:\n"); printf_stack(&s2); /*************************************************运用后缀表达式求结果********************************/ int count_=count(&s2,&s1); printf("计算出来的结果为:%d\n",count_); return 0; }
如有疑问,请及时提出,谢谢!!
相关文章推荐
- 【数据结构与算法】实现四则运算
- 数据结构实验之实现两个复数的四则运算
- 数据结构之单链表及python实现
- 数据结构模版----单链表SimpleLinkList[不带头结点](C语言实现)
- python 数据结构之单链表的实现
- 数据结构基础(12) --双向循环链表的设计与实现
- 数据结构与算法|Java实现单链表
- 数据结构之hash表,HashMap简单实现
- 数据结构图文解析之:二叉堆详解及C++模板实现
- 12、数据结构笔记之十二栈的应用之栈与递归之阶乘实现
- JSON复杂数据处理之Json树形结构数据转Java对象并存储到数据库的实现
- 数据结构之单链表的基本实现
- mysqldump只导出表结构或只导出数据的实现方法【转】
- 数据结构之数组实现栈结构
- 根据数据的父子关系创建树形结构并实现遍历
- 【数据结构与算法】左偏树(堆)的实现
- 经典数据结构之数组实现的队列
- 数据结构之二叉树的Java实现
- 数据结构(五)——二叉树(C语言实现)
- 看数据结构写代码(16)顺序队列的实现(循环队列)