栈的应用
2016-05-17 13:01
447 查看
思路:
先将字符串进行化简——多位整数,单位整数,浮点数和字符分开
构造一个结构体类型的数组s,存储化简后的中缀表达式
构造一个结构体类型的栈,进行转换
构造一个结构体类型的数组l,存储后缀表达式
构造一个结构体类型的栈,计算后缀表达式
一.存储
二.中缀表达式转后缀表达式
三.后缀表达式输出
先将字符串进行化简——多位整数,单位整数,浮点数和字符分开
构造一个结构体类型的数组s,存储化简后的中缀表达式
构造一个结构体类型的栈,进行转换
构造一个结构体类型的数组l,存储后缀表达式
构造一个结构体类型的栈,计算后缀表达式
一.存储
gets比较方便输入,扫描字符串,将字符串存入到s中;
二.中缀表达式转后缀表达式
扫描中缀表达式 1.遇到操作数:直接输出(添加到后缀表达式中) 2.栈为空时,遇到运算符,直接入栈 3.遇到左括号:将其入栈 4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。 5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
三.后缀表达式输出
<pre name="code" class="cpp">设置一个栈,开始时,栈为空; 然后从左到右扫描l中的后缀表达式,若遇操作数,则进栈; 若遇运算符,则从栈中退出两个元素,运算后的结果再进栈,直到后缀表达式扫描完毕。 此时,栈中仅有一个元素,即为运算的结果。
/********************************************************* 1.支持多位正整数,正浮点数 2.支持加减乘除 3.支持空格 4.支持回车空输入 5.支持多次输入 6.除以0检错 7.支持表达式合法检测 :首末不能有字符(可以有'('或')') :括号必须成对 :字符不能连续出现 :左括号的左边不能为数字,右边不能为符号 :右括号的左边不能为符号,右边不能为数字 //尚未解决 :负数运算 *********************************************************/
#include <cstdio> #include <cstdlib> #include <iostream> #include <stack> #include <queue> #include <algorithm> #include <cstring> #include <cmath> #include <vector> #include <bitset> #include <list> #include <sstream> #include <set> #include <functional> using namespace std; #define Max_ 0X3f3f3f3f int i = 0; int j = 0; int k = 0; int m = 0; int zuo; int you; int begin; int end = Max_; int illegal; char in[Max_] = {0}; struct sta { int order; int flag = 0;//1为int,2为float,3为char int data1; double data2; char data3; }s[1000],out,l[1000]; stack <sta> hello; stack <sta> world; //判断是否为数字 int number(char c) { if ((c>='0'&&c<='9')||(c=='.')) return 1; else return 0; } //判断是否为合法字符 int mark(char c) { if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#') return 1; else return 0; } //判断结构体是否为存数的结构体 int shu(struct sta c) { if((c.flag == 1)||(c.flag == 2)) return 1; else return 0; } //判断结构体是否为存符号的结构体 int fu(struct sta c) { if(c.flag == 3) return 1; else return 0; } //删除空格 void delete_space() { char c; for (int i = 0; i < strlen(in); i += 1) { if (in[i] == ' ') { int j; for (j = i; j < strlen(in)-1; j += 1) { in[j] = in[j+1]; } in[j] = '\0'; } } } void print(struct sta r) { if(r.flag == 1){ printf("%d",r.data1); } else if(r.flag == 2){ printf("%lf",r.data2); } else if(r.flag == 3){ printf("%c",r.data3); } } void test() { for(int j = 0;j < k;j++) { print(s[i]); } printf("\n"); } //多位数或浮点数的处理 void deal(int sta,int en)//youwenti { //printf("%d%d\n",sta,en);//start end ok int fla = 0,point; for(int i = sta;i<=en; i++)//区分浮点数还是多位数,ok { if(in[i] == '.'){ fla = 1; point = i; break; } } if(fla)//浮点数 { //printf("Fudianshu\n"); double sum = 0; for(int j = sta;j<point;j++){ sum += (in[j]-'0')*(float)pow(10,point-j-1); } for(int j = point+1;j<=en;j++){ sum += (in[j]-'0')*(float)pow(10,point-j); } s[k].flag = 2; s[k].data2 = sum; // printf("%d ",k); // printf("%lf\n",s[k].data2); s[k].order = k; k++; } else//多位整数 { //printf("Duoweizhengshu"); int sum = 0; int a = en-sta; for(int j = sta;j <= en;j++) { sum += (in[j]-'0')*(float)(pow(10,a)); //printf("%d\n",sum); a--; } s[k].flag = 1; s[k].data1 = sum; // printf("%d %d\n",k,s[k].data1); s[k].order = k; k++; } return ; } void store()//存储到s { memset(s,0,sizeof(s[0])); begin = 0; for (i = 0; i < strlen(in); i += 1) { if(mark(in[i])){//字符 begin = i+1; s[k].flag = 3; s[k].data3 = in[i]; //printf("%c\n",s[k].data3); k++; } else if(number(in[i])){//数字 for(int j = i+1;j<=strlen(in);j++){ if(mark(in[j])||(j==strlen(in))){ i = j-1;//下位调到字符继续搜索 end = j-1; break; } } if(end-begin){ deal(begin,end); } else{//单位整数ok s[k].flag = 1; s[k].data1 = (in[i]-'0'); //printf("%d %d\n",k,s[k].data1); k++; } } } return ; } void judge() { for(int j = 0; j < k; j++)//判断括号 { if(fu(s[j])){ if(s[j].data3=='(') { zuo++;//右边不能为字符 if((j+1<k)&&((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/'))) { illegal = 2; return ; } if((j-1>=0)&&(shu(s[j-1])))//左边不能为数字 { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } if(((j+1<k)&&(s[j+1].data3==')'))||(j==k-1))//空格中不能为空,不能放鸽子;不能为尾 { illegal = 2; return ; } } else if(s[j].data3==')') { you++;//左边不能为字符 if((j-1>=0)&&((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/'))) { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } if(((j+1<k)&&(shu(s[j+1])))||(j==0))//右边不能为数字;不能为首 { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } } else if((s[j].data3=='+')||(s[j].data3=='-')||(s[j].data3=='*')||(s[j].data3=='/')) { if((j==0)||(j==k-1))//首尾不能为字符 { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } else if((s[j-1].data3=='+')||(s[j-1].data3=='-')||(s[j-1].data3=='*')||(s[j-1].data3=='/')) { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } else if((s[j+1].data3=='+')||(s[j+1].data3=='-')||(s[j+1].data3=='*')||(s[j+1].data3=='/')) { //printf("Ilegal expression,please input again\n"); illegal = 2; return ; } } } } if(zuo!=you){ printf("Ilegal expression,please input again\n"); illegal = 2; return ; } } void in_data()//ok { memset(in,0,sizeof(in[0])); illegal = 0; k = 0; zuo = 0; you = 0; printf("Please input:"); gets(in);//输入 delete_space(); if(strlen(in)==0){//不断回车,跳过 illegal = 3; return ; } if(in[0] == '#'){//结束符 illegal = 1; return ; } for(i = 0;i < strlen(in);i++) { if(!mark(in[i]) && !number(in[i])){// printf("Wrong inputs!\n"); illegal = 3; return ; } } store();//存储 judge();//表达式的判断 //printf("%d",k); return ; } int nless(char a,char b)//a>=b { if((a=='(')&&(b!='(')){ return 0; } else if(a=='+'||a=='-'){ if(b=='*'||b=='/'){ return 0; } } else return 1; } void middle_later()//扫描s,l赋值有问题 { memset(l,0,sizeof(l[0])); while(!hello.empty()){ hello.pop(); } m = 0; printf("Postfix Expression:"); for(int j = 0;j < k; j++) { //栈为空时,遇到运算符直接入栈 if(hello.empty()&&fu(s[j])){ hello.push(s[j]); } //遇到操作数,直接输出 else if(shu(s[j])){ print(s[j]); l[m] = s[j]; m++; printf(" "); } //遇到左括号,入栈 else if(fu(s[j])&&s[j].data3 == '('){ hello.push(s[j]); } //遇到右括号,执行出栈操作,直至弹出的栈为左括号,左括号不输出 else if(fu(s[j])&&s[j].data3 == ')'){ while(!hello.empty()) { out = hello.top(); if(out.data3 != '('){ print(out); l[m] = out; m++; printf(" "); hello.pop(); } else{ hello.pop(); break; } } } //遇到加减乘除,弹出所有优先级不小于该运算符的栈顶元素,然后将该运算符入栈 else if(fu(s[j])) { while(!hello.empty()) { out = hello.top(); if(nless(out.data3,s[j].data3)) { print(out); l[m] = out; m++; printf(" "); hello.pop(); } else break; } hello.push(s[j]); } } while(!hello.empty()) { out = hello.top(); print(out); l[m] = out; m++; printf(" "); hello.pop(); } printf("\n"); // for(int j = 0; j < k; j++) // { // print(l[j]); // } // printf("\n"); } double data(struct sta c) { if(c.flag==1) return c.data1; else if(c.flag==2) return c.data2; } void with(struct sta b,char c,struct sta a) { struct sta d; double ans = 0; switch(c) { case '+':ans = data(b)+data(a);break; case '-':ans = data(b)-data(a);break; case '*':ans = data(b)*data(a);break; case '/': { if(data(a)==0) { printf("No ends,sorry\n"); illegal = 2; return ; } ans = data(b)/data(a); break; } } d.flag = 2; d.data2 = ans; world.push(d); return ; } void later_out() { struct sta a,b; while(!world.empty()){ world.pop(); } for(int j = 0; j < m; j++) { //print(l[j]);//ok if(shu(l[j])){ world.push(l[j]); } else if(fu(l[j])) { a = world.top(); world.pop(); b = world.top(); world.pop(); with(b,l[j].data3,a); if(illegal==2) return ; } } printf("Answer:"); print(world.top()); printf("\n\n"); return; } int main(int argc, char const* argv[]) { while (1) { //输入及存储 in_data(); if(illegal == 1) break; if(illegal == 2){printf("Ilegal expression,please check again\n");continue;} if(illegal == 3) continue; //中缀转后缀 middle_later(); //后缀计算输出 later_out();//youcuowu if(illegal == 2) continue; } return 0; }
相关文章推荐
- 将中缀表达式转化为后缀表达式
- 图解后缀表达式的计算过程
- 接触后缀表达式(逆波兰表示法)
- 前缀表达式,中缀表达式,后缀表达式转化和计算
- 中缀表达式与后缀表达式
- Python实现Shuntingyard (调度场)算法
- leetcode题目--Evaluate Reverse Polish Notation 答案
- [python]将中缀表达式(infix)转换为后缀表达式(postfix)
- 字符串转化为数学表达式并求值(后缀表达式)
- 栈的简单应用——四则运算(三)
- 栈的简单应用——四则运算(一)
- 使用堆栈计算后缀表达式--java实现
- poj 中缀表达式的值
- 用java实现计算String类型的四则运算——用栈和后缀表达式实现
- hdoj 1022 Train Problem I(用栈解决法)
- 括号配对(栈的应用!)
- 后缀表达式总结
- 四则运算表达式
- 括号匹配算法
- mysql中or和in的效率问题