逆波兰表达式计算(后缀表达式,中缀转后缀)
2015-08-28 17:28
621 查看
/* 后缀表达式计算 中缀表达式转后缀表达式 */ #include<iostream> #include<cstdlib> #include<cctype> using namespace std; template<class T> class stack { private: T* base; T* top; int stackSize; public: stack(int a=100):stackSize(a) { base=top=new T[stackSize]; } ~stack() { delete [] base; base=top=NULL; cout<<"stack析构\n"; } bool is_empty()const; bool is_full()const; bool pop(T &a); bool push(T a); int len()const; }; template<class T> bool stack<T>::is_empty()const { if(base==top) return true; else return false; } template<class T> bool stack<T>::is_full()const { if(top-base==stackSize) return true; else return false; } template<class T> bool stack<T>::push(T a) { if(!is_full()) { *(top++)=a; return true; } else return false;; } template<class T> bool stack<T>::pop(T& a) { if(!is_empty()) { a=*(--top); return true; } else return false; } template<class T> int stack<T>::len()const { cout<<(int*)base<<endl; cout<<(int*)top<<endl; return top-base; } double postfix(char* str) // 计算后缀表达式 { char c; stack<double>s; char bluff[10]; int j=0; c=str[j++]; while(c!='#') { int i=0; while(isdigit(c) || c=='.')//处理的数是double型的 { bluff[i++]=c;// 用一块缓存区存储char型数据后转换 if(i>=10) { printf("\n输入的数过大\n"); return 1; } c=str[j++]; if(' '==c) // 处理数字后的空格,符号后的空格不管 { bluff[i]='\0'; i=0; s.push(atof(bluff)); break; } } if('+'==c || '-'==c || '*'==c || '/'==c) { double d,e; s.pop(d); s.pop(e); switch(c) { case '+': s.push(d+e); break; case '-': s.push(e-d);// 后出的减去前出的 break; case '*': s.push(e*d); break; case '/': if(d !=0) s.push(e/d); else { printf("\n除数不能为0\n"); return 1; } break; default: printf("\n符号不能识别\n"); return 1; } } c=str[j++]; } double ans; s.pop(ans); return ans; } char* mid2post(char* str, char*& str2)// 人机友好的中缀转换为合适计算机处理的后缀表达式 { int i=0,j=0; stack<char>s; char e; char c=str[j++]; while(c!='#') { while(isdigit(c) || '.'==c) { str2[i++]=c; c=str[j++]; //看下一个数是否还是数字 if(' '==c || '#'==c) //空格结束,这里容易出错 { str2[i++]=' '; break; } } if(')'==c) //遇到右括号,栈里肯定有符号 { s.pop(e); while('('!=e) { str2[i++]=e; str2[i++]=' '; s.pop(e); } } else if('+'==c || '-'==c)// { if(s.is_empty())//栈空,压栈 { s.push(c); } else //里面的优先级都高于这个+- { do { s.pop(e);//弹出前面的符号,直到栈空或者遇到左括号 if('('==e) { s.push(e); } else { str2[i++]=e; str2[i++]=' '; } }while('('!=e && !s.is_empty()); s.push(c);// 取出来后别忘了把这个符号再压栈 } } else if('*'==c || '/'==c || '('==c)//保证栈里的符号优先级总是较低的 { s.push(c); } if('#'==c) break; c=str[j++]; } while(!s.is_empty()) { s.pop(e); str2[i++]=e; str2[i++]=' '; } str2[--i]='#';//'#'之前不要空格,和逆波兰表达式匹配 str2[++i]='\0'; cout<<"后缀表达式:"<<str2<<endl; return str2; } double midfix(char *str)// 计算中缀表达式 { //cout<<str<<endl; char* str2=new char[100]; mid2post(str,str2); double ans=postfix(str2); delete str2; return ans; } int main() { char str[100]; //printf("输入逆波兰表达式,元素之间用空格分开,并以#结束\n"); //cin.getline(str,100); //cout<<str<<endl; //printf("\n计算结果是%f\n",postfix(str)); printf("输入中缀表达式,元素之间用空格分开,并以#结束\n"); cin.getline(str,100); cout<<midfix(str)<<endl; return 0; }
相关文章推荐
- PF_PACKET笔记
- 关于安卓工程导出带res资源文件的jar的总结
- spring bean id和name
- 程序员在职业生涯中如何规划自己
- 左连接 竖表查横表
- 如何使用 fail2ban 防御 SSH 服务器的暴力破解攻击
- hdu 4704 Sum(隔板+费马小定理·大数取模)
- maven环境快速搭建
- 关于C++中的友元函数的总结
- AJAX POST 与 GET 的区别 && HTTP
- centos7 网卡配置
- Flex4 DateField自定义的日期选择控件,可选择时分秒
- java中导入了包却无法调用包中方法问题解决
- 【转】[Mysql] Linux Mysql 日志专题
- Android基础入门教程——5.2.1 Fragment实例精讲——底部导航栏的实现(方法1)
- django 1.8 官方文档翻译: 3-2-1 内建的视图
- 网络拓扑图
- iPad开发第一天
- 安装语言选项
- 828