表达式求值
该版本的数字都是1位,我还要改进下。还没支持负号以及指数操作
/*
操作符优先级:(从大到小) ‘(’ —— ‘ * ’ 或 ‘ / ’ —— '+' 或 ‘-’ —— ‘ )’ ;(把括号也看作操作符)
思路:用两个栈,一个操作符栈,一个数据栈,顾名思义,数据栈存表达式的数据,操作符栈存 ()+ - * / 等。
将中缀表达式转换为后缀表达式,在转换的过程中求表达式的值!
具体步骤如下:(下面思路假设数据都是一位数的整数,便于理解,具体数字处理在代码中体现)
先将 一个’=‘ 放入 操作符栈
1:读取表达式的一个字符;
2: 若为数字存入数据 栈 转至1;
3:若为操作符:比较操作符栈顶 和 该操作符的 优先级
① pk函数返回值 为 ’>‘(若操作符栈顶优先级大于或等于该操作符的优先级):栈顶操作符出栈(假设操作符为-) ,从数据栈出两个数据(假设第一个是y,第二个 是x),计算值(x-y),注意数据顺序!!将值放入 数据栈!转至 3;
② pk函数返回值为’<‘ (若操作符栈顶优先级小于该操作符的优先级): 讲该 操作符放入 操作符栈,转至 1;
③ pk函数返回值为’=‘ (具体看代码) 将操作符栈顶的操作符出栈,转至1;
4:输出数据栈栈顶值即可!
*/
#include <iostream>
#include <stack>
//#include <cctype>
#include <cstring>
#include <string>
using namespace std;
/*
( * / + - ) #
( 1 1 1 1 1 0 1
* -1 1 1 1 1 1 1
/ -1 1 1 1 1 1 1
+ -1 -1 -1 1 1 1 1
- -1 -1 -1 1 1 1 1
) 0 -1 -1 -1 -1 1 1
# -1 -1 -1 -1 -1 -1 0
*/
int matrix[7][7]
={
{ 1, 1, 1, 1, 0, 1},
{ -1, 1, 1, 1, 1, 1},
{ -1, 1, 1, 1, 1, 1},
{ -1, -1, -1, 1, 1, 1},
{ -1, -1, -1, 1, 1, 1},
{ 0, -1, -1, -1, 1, 1},
{ -1, -1, -1, -1, -1, 0}
};
char expr[1000] = {0};
int getIndex(char ch);
int pk(char c1,char c2);
int oper(int x,char c,int y);
int myisdigit(char ch)
{
if (ch >='0' && ch <= '9')
return 1;
return 0;
}
void Infix2Post(string & poststr);
int getVal(const string & poststr);
int main(int argc, char *argv[])
{
freopen("1101.data","r",stdin);
while (cin >> expr)
{
stack<char> operators;
stack<int> num;
string poststr("");
int i;
Infix2Post(poststr);
// cout << poststr<<endl;
cout << getVal(poststr)<<endl;
}
return 0;
}
void Infix2Post(string & poststr){
stack<char> operators;
operators.push('#');
// 将中序变后序
for (int i=0;i<strlen(expr) ;i++ )
{
char ch = expr[i];
if(myisdigit(ch)){
poststr+= ch;
}else{
if( ch=='(' ) operators.push(ch);
else if( ch==')' ){
if (operators.empty())
{ //cout << "()error" <<endl;exit(-1);
}
while(!operators.empty() && operators.top() != '(' ){
char top = operators.top();
operators.pop();
poststr+= top;
}
if (operators.top() == '(')
{operators.pop();
}
}else{
char top=operators.top();
if (top=='('||pk(top,ch)<0)
{
operators.push(ch);
}else{
while( !operators.empty() && top!='(' && pk(top,ch)>0 ){
operators.pop();
poststr+= top;
top = operators.top();
}
operators.push(ch);
}
}
}
}
while( !operators.empty()){
char top = operators.top();operators.pop();
poststr+= top;
}
}
int getVal(const string & poststr)
{
stack<int> stk;
for(int i=0;i<poststr.length()-1;i++)
{
if ( myisdigit(poststr[i]) )
{stk.push(poststr[i]-'0');
}else {
int y = stk.top();stk.pop();
int x = stk.top();stk.pop();
stk.push(oper(x,poststr[i],y));
}
}
return stk.top();
}
int getIndex(char ch)
{
int index = 0;
switch(ch)
{
case '(':index = 0;break;
case '*':index = 1;break;
case '/':index = 2;break;
case '+':index = 3;break;
case '-':index = 4;break;
case ')':index = 5;break;
case '#':index = 6;break;
}
return index;
}
int pk(char c1,char c2)
{
return matrix[getIndex(c1)][getIndex(c2)];
}
int oper(int x,char c,int y)
{
if(c=='+') return x+y;
else if(c=='-') return x-y;
else if(c=='*') return x*y;
else return x/y;
}