思路:
使用两个栈分别保存运算符和操作数。将表达式从左到右依次送人栈中处理:
- 将操作数压人操作数栈。
- 将运算符压人运算符栈。
- 忽略左括号。
- 若遇到右括号,则弹出一个运算符,并弹出所需的操作数,并将这部分表达式的运算结果求出后压人操作数栈。
- 处理完所有右括号后,操作数栈中的最后一个指就是表达式的值。
代码:
#include<iostream>
#include<sstream>
#include<string>
#include<stack>
using namespace std;
template<typename T>
T strToNum(const string& str)
{
istringstream istr(str);
T num;
istr >> num;
return num;
}
int main(void)
{
string exp;
stack<double> vals;//operand stack
stack<string> ops;//operator stack
while(cin >> exp,!cin.eof())//"ctrl+z" for console EOF
{
if(cin.bad())
{
cerr << "error:IO stream corrupt " << endl;
}
if(cin.fail())
{
cerr << "bad data!try again!" << endl;
cin.clear();
cin.sync();
continue;
}
// cout << exp <<endl;
if(string("+") == exp)
{
ops.push(exp);
}
else if(string("-") == exp)
{
ops.push(exp);
}
else if(string("*") == exp)
{
ops.push(exp);
}
else if(string("/") == exp)
{
ops.push(exp);
}
else if(string("(") == exp)
{}
else if(string(")") == exp)
{
double val = vals.top();
vals.pop();
string op = ops.top();
ops.pop();
if(string("+") == op)
{
val = vals.top() + val;
vals.pop();
}
else if(string("-") == op)
{
val = vals.top() - val;
vals.pop();
}
else if(string("*") == op)
{
val = vals.top() * val;
vals.pop();
}
else if(string("/") == op)
{
val = vals.top() / val;
vals.pop();
}
vals.push(val);
}
else
{
//method 1:
//double operand = strToNum<double>(exp);
//method 2:
double operand = stod(exp);//cast string to num.c++11
cout << operand <<endl;
vals.push(operand);
}
}
cout << "ret-->" <<vals.top();
getchar();
return 0;
}
代码只考虑了每个操作符构成的表达式都用括号括起来的情况。
心得体会:
c++的stack适配器的pop函数只是执行出栈操作并不返回栈顶元素。top函数是返回栈顶元素。
题目:
编写一段程序,从标准输入得到一个缺少左括号的表达式并打印出补全括号之后的中缀表达式。(这里也只考虑每个操作符构成的表达式都用括号括起来的情况)
思路:
借鉴上面的思路。上面是在操作符和对应操作数出栈后计算出它们的值后再压人操作数栈,这里为了还原表达式所以不需要计算出表达式的值,而是应该将整个表达式(包括左右括号)压人操作数栈。
代码:
#include<iostream>
#include<sstream>
#include<string>
#include<stack>
using namespace std;
int main(void)
{
string exp;
stack<string> vals;//operand stack
stack<string> ops;//operator stack
while(cin >> exp,!cin.eof())//"ctrl+z" for console EOF
{
if(cin.bad())
{
cerr << "error:IO stream corrupt " << endl;
}
if(cin.fail())
{
cerr << "bad data!try again!" << endl;
cin.clear();
cin.sync();
continue;
}
// cout << exp <<endl;
if(string("+") == exp)
{
ops.push(exp);
}
else if(string("-") == exp)
{
ops.push(exp);
}
else if(string("*") == exp)
{
ops.push(exp);
}
else if(string("/") == exp)
{
ops.push(exp);
}
else if(string("(") == exp)
{}
else if(string(")") == exp)
{
string val = vals.top();
vals.pop();
string op = ops.top();
ops.pop();
if(string("+") == op)
{
val = string("(")+vals.top() +string("+")+ val+string(")");
vals.pop();
}
else if(string("-") == op)
{
val = string("(")+vals.top() +string("-")+ val+string(")");
vals.pop();
}
else if(string("*") == op)
{
val = string("(")+vals.top() +string("*")+ val+string(")");
vals.pop();
}
else if(string("/") == op)
{
val = string("(")+vals.top() +string("/")+ val+string(")");
vals.pop();
}
vals.push(val);
}
else
{
vals.push(exp);
}
}
cout << "ret-->" <<vals.top();
getchar();
return 0;
}
参考:http://blog.csdn.net/k346k346/article/details/50927002----C++数值类型与string的相互转换