中缀表达式转换为后缀表达式(以STL中的stack为工具)pta
栈的基本结构
这是一种先进后出的数据结构。可以类比到生活中的羽毛球筒,最先放进去的羽毛球最后取出来。
常用函数
stack<Typename> 定义栈名。
stack<int>S;
S.push(x); // 往栈中压入x元素
S.pop(); //弹栈
S.empty() //判栈空,如果为空,则返回值为1,否则,为0;
S.top();
stack<int>S; //定义一个int类型的栈
for(int i = 1;i <= 10;i ++) // 依次往栈里压入元素
S.push(i);
while(!S.empty()){ //判栈空
cout << S.top() << end; //取栈顶并输出
S.pop(); //将栈顶弹出
}
中缀表达式转换为后缀表达式
例题
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
思路
采用两个栈来存放元素,这里的元素定义为string类型,因为既有字符也有数字(如果用int类型来存放就会有局限性,用阿斯科码来表示,比如说如果出现小数);
同时还要处理运算符之间的关系。
代码(小数、数字前带符号,带括号的中缀转后缀)
#include<stack>
#include<string>
#include<iostream>
using namespace std;
string str;
int judge[7][7]{ //用一个二维数组来存放各个元素个关系
{0,0,-1,-1,1,-1}, //小于0,表示第一个下标对应的符号比第二个
{0,0,-1,-1,1,-1}, //符号的优先级高
{1,1,0,0,1,-1},
{1,1,0,0,1,-1},
{-1,-1,-1,-1,0,-1},
{1,1,1,1,1,0}
}; // 一共有7维,因为还有‘(’的关系,‘)’的情况会特判
string num(int * i){ // 获取当前位置往后得属于数字部分的字符串
int pos = *i;
int begin = pos;
while((str[pos]=='.'||(str[pos] >= '0' && str[pos] <= '9')) && pos < str.length()) pos ++;
*i = pos - 1;
return str.substr(begin,pos - begin);
}
int turn(char x){
if(x == '#') return 4;
if(x == '+') return 0;
if(x == '-') return 1;
if(x == '*') return 2;
if(x == '/') return 3;
if(x == '(') return 5;
}
int check(char a,char b){ // 判断优先级的函数
int n = turn(a);
int m = turn(b);
return judge[n][m];
}
int main(){
stack<string> a;
stack<string> b;
b.push("#");
cin >> str;
for(int i = 0;i < str.length();i ++){
if(str[i] == '(') b.push(str.substr(i,1));
else if((str[i - 1]=='('|| i == 0)&&(str[i] < '0' || str[i] > '9')){
i += 1;
a.push(str[i - 1] + num(&i));
}
else if(str[i] <= '9' && str[i] >= '0'){
string now = num(&i);
a.push(now);
}
else {
if(str[i]=='(') b.push(str.substr(i,1));
else if(str[i]==')'){
while(b.top()!="("){
string now = b.top();
b.pop();
a.push(now);
}
b.pop();
}
else if(check(str[i],b.top()[0]) > 0){
b.push(str.substr(i,1));
}
else {
while((check(str[i],b.top()[0]) <= 0)&&b.top() != "("){
string now = b.top();
b.pop();
a.push(now);
}
b.push(str.substr(i,1));
}
}
}
while(b.top() != "#"){
string now = b.top();
b.pop();
a.push(now);
}
stack<string> ans;
while(!a.empty()){
string now = a.top();
a.pop();
ans.push(now);
}
while(!ans.empty()){
if(ans.top()==")"||ans.top()=="("){
ans.pop();
continue;
}
if(ans.top()[0] == '+'&&ans.top().length() > 1)
ans.top().erase(0,1);
cout << ans.top();
if(ans.size() > 1) cout << " ";
ans.pop();
}
return 0;
}