栈的应用
来源:互联网 发布:去向分布图用什么软件 编辑:程序博客网 时间:2024/06/18 15:04
思路:
先将字符串进行化简——多位整数,单位整数,浮点数和字符分开
构造一个结构体类型的数组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_ 0X3f3f3f3fint 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;}
1 0
- 栈&栈的应用
- 栈的应用
- 栈的应用
- 简单的栈应用
- 栈的应用
- 栈的简单应用
- 栈的应用
- 栈的应用
- hdu1022栈的应用
- 栈的应用举例
- 栈的应用
- 栈的简单应用
- 数据结构栈的应用
- 栈的简单应用
- 栈的简单应用
- 栈的应用
- 栈的应用
- 栈的经典应用
- Android测试有用工具笔记
- POJ 3525 二分答案,推进多边形和半平面交
- eclipse运行maven install报错
- mysql中or和in的效率问题
- HTML和HTML5的学习
- 栈的应用
- 一些关于dagger2的理解(二)
- 第十二周实践项目课后————4
- Python 资源大全
- iOS设置状态栏
- 150. Evaluate Reverse Polish Notation【M】【19】
- Unity 脚本 自动添加 脚本信息
- 手把手,嘴对嘴,Fragment使用
- IOS完整学习路线图,希望可能帮助IOS童鞋