C++学习之(栈) 实践之(逆波兰公式)
来源:互联网 发布:凸优化 求解 编辑:程序博客网 时间:2024/05/21 09:07
栈(statck)这种数据结构在计算机中是相当出名的。栈中的数据是先进后出的(First In Last Out, FILO)。栈只有一个出口,允许新增元素(只能在栈顶上增加)、移出元素(只能移出栈顶元素)、取得栈顶元素等操作。在STL中,栈是以别的容器作为底部结构,再将接口改变,使之符合栈的特性就可以了。因此实现非常的方便。在STL中栈一共就5个常用操作函数(top()、push()、pop()、 size()、empty() ),很好记的。
#include <iostream>#include <vector>#include <stack>#include <list>using namespace std;int main(){//定义栈 使用list作为容器stack<int,list<int>> a; stack<int,vector<int>> b; int i;//压入栈数据for(i = 0;i < 10;i++){a.push(i);b.push(i);}//输出栈size的大小cout<<"a stack size : " << a.size()<<endl;//取栈项数据并将数据弹出栈 cout<<"a 中的数据:";while(!a.empty()){ cout<<a.top()<<" "; //栈顶元素弹出栈 a.pop();}cout<<endl;cout<<"b 中的数据:";while(!b.empty()){ cout<<b.top()<<" "; //栈顶元素弹出栈 b.pop();}system("pause"); return 0;}
栈的实践使用:逆波兰公式
表达式一般由操作数(Operand)、运算符(Operator)组成,例如算术表达式中,通常把运算符放在两个操作数的中间,
这称为中缀表达式(Infix Expression),如A+B。
波兰数学家Jan Lukasiewicz提出了另一种数学表示法,它有两种表示形式:
把运算符写在操作数之前,称为波兰表达式(Polish Expression)或前缀表达式(Prefix Expression),如+AB;
把运算符写在操作数之后,称为逆波兰表达式(Reverse Polish Expression)或后缀表达式(Suffix Expression),如AB+;
其中,逆波兰表达式在编译技术中有着普遍的应用。
算法:
一、 将中缀表达式转换成后缀表达式算法:
1、从左至右扫描一中缀表达式。
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
3、若读取的是运算符
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
二、逆波兰表达式求值算法:
对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
- 初始化一个空堆栈
- 从左到右读入后缀表达式
- 如果字符是一个操作数,把它压入堆栈。
- 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
- 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。
<pre name="code" class="cpp">#include <iostream>#include <stack>#include <list>using namespace std;//声明函数bool isOperand(char c);bool isOpertor(char c);bool ComaprePriority(char op1,char op2);int getPriorityValue(char c);int Operate(char op, int operand1, int operand2);//判断是否为数字bool isOperand(char c){ return ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' );}//判断是否为运算符bool isOpertor(char c){ return ( c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' );}//判断运算符优先级大小 op1优先级高于或者等于op2返回truebool ComaprePriority(char op1,char op2){return (getPriorityValue(op1) >= getPriorityValue(op2)) ;}//获取运算符优先级int getPriorityValue(char c){int prioityValue;switch(c){case '+ ':prioityValue = 1;break;case '-':prioityValue = 1;break;case '*':prioityValue = 2;break;case '/':prioityValue = 2;break;default:prioityValue = 0;}return prioityValue;}int Operate(char op, int operand1, int operand2){ switch(op) { case '+': return operand1 + operand2; case '-': return operand1 - operand2; case '*': return operand1 * operand2; case '/': return operand1 / operand2; default: return -1; }}int main(){//定义栈 使用list作为容器stack<char> operand; stack<char> opertor; char str[20] = "(2+4)*4+1";//压入栈数据int length = strlen(str);for(int i = 0;i < length;i++){char c = str[i];cout<<c<<" ";//判断是否为操作数if (isOperand(c)){operand.push(c);}else{//为运算符//若运算符为"("直接存入到运算符栈中if( c == '('){opertor.push(c);}else if(c == ')'){//该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。while(opertor.top() != '('){char op = opertor.top();opertor.pop();operand.push(op);}//将'('出栈opertor.pop();}else{ // 该运算符为非括号运算符: // (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。 //考虑栈顶为空的情况 if(opertor.empty()) {opertor.push(c);continue; } if(opertor.top() == '(') {opertor.push(c); } else { //(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。 if(ComaprePriority(c,opertor.top())) {opertor.push(c); } else {// (c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。char op = opertor.top();operand.push(op);opertor.pop();opertor.push(c); }// if(ComaprePriority(c,opertor.top())) }//end if(opertor.top() == '(')}//end if( c == '(')}//end if (isOperand(c))}//end for//4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。while(!opertor.empty()){char op = opertor.top();operand.push(op);opertor.pop();}//cout<<endl<<"转换后的逆波兰表达式:";//输出转换后的逆波兰表达式//while(!operand.empty())//{//cout<<operand.top()<<" ";//operand.pop();//}//计算逆波兰表达式stack<char> stackOper;stack<int> stackresult;//计算使用栈//上面计算后的栈是反着的 把它倒转过来计算while(!operand.empty()){//cout<<operand.top()<<" ";char op = operand.top();stackOper.push(op);operand.pop();}//计算逆波兰表达式while(!stackOper.empty()){char op = stackOper.top();//如果字符是一个操作数,把它压入堆栈。 if (isOperand(op)){int num ;num = atoi(&op);stackresult.push(num);}else{//如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。int number1 = stackresult.top();stackresult.pop();int number2 = stackresult.top();stackresult.pop();//弹出两个操作符执行运算int result = Operate(op,number1,number2);stackresult.push(result);}stackOper.pop();}//输出计算结果cout<<" = " << stackresult.top()<<endl;system("pause"); return 0;}
- C++学习之(栈) 实践之(逆波兰公式)
- C#学习之逆波兰公式简单实现
- C#学习之逆波兰公式简单实现
- 数据结构学习之栈-逆波兰表达式(一)
- EXCEL之:公式的逆波兰序表达式
- 栈之逆波兰计算器
- 算法学习一之逆波兰表达式
- 算法学习之递归--逆波兰表达式
- stack应用之逆波兰
- 计算器之逆波兰算法
- leetcode之逆波兰求值
- 【递归】 之 逆波兰表达式
- 数据结构之逆波兰表达式
- lintcode之逆波兰表达式
- 逆波兰计算器(C语言)
- 逆波兰计算器(C语言)
- 波兰表达式和逆波兰表达式(栈)
- 逆波兰表达式学习日记(1)
- So cute are you python 14
- 联想A790E的root方法
- Flex多样化饼图样式(颜色渐变,点击分离,环形)
- uva 10491 - Cows and Cars(概率)
- UVA 11584 Partitioning by Palindromes 回文串dp
- C++学习之(栈) 实践之(逆波兰公式)
- android webview loaddata乱码问题
- 数论小结 写的很好!!!赞一个
- POJ 放苹果
- linux 线程 信号
- matlab 问题汇总
- WebService——wsimport命令建立webService本地客户端
- linux--嵌入式网络文件系统(NFS)搭建原理
- C语言sprintf函数