中缀转后缀
1. 扫描字符串,遇到数字输出,遇到操作符c
栈顶操作符的权值小于c,直接入栈
栈顶操作符的权值大于等于c,依次弹出,直到栈顶权值小于c,c入栈
2. 括号需要特别处理,入栈之前与入栈之后,括号的优先级发生变化
‘(’在栈外权值最大,即无条件入栈
‘(‘在栈内权值最小,即任何其他(除‘)’外)操作符,都可入栈
当遇到‘)’时,一切‘(’与‘)’之间的操作符全部出栈,当然‘(’也要出栈。
//栈内权值
int inOrder(char c)
{
switch (c)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 0;
case ')':
return 3;
default:
return -1;
}
}
//栈外操作符权值
int outOrder(char c)
{
switch (c)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 3;
case ')':
return 0;
default:
return -1;
}
}
右上可见,只有括号在栈内与栈外的权值不同。
bool isOperator(char c)
{
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
return true;
default:
return false;
}
}
char DELIMITER = ',';
string toPost(string infix)
{
string postfix;
bool error = false;
bool state = false;
stack<char> op;
if (infix.size() == 0)
return "";
for (int i = 0; i< infix.size(); i++)
{
char c = infix[i];
if (isdigit(c))
{
postfix.push_back(c);
state = true;
}
else if (isOperator(c))
{
if (state)
{
postfix.push_back(DELIMITER);
state = false;
}
while (!op.empty() && inOrder(op.top()) > outOrder(c))
{
postfix.push_back(op.top());
postfix.push_back(DELIMITER);
op.pop();
}
if (c == ')' && op.empty() || c == ')' && op.top() != '(')
{
error = true;
break;
}
else if ( c == ')')
op.pop();
else
op.push(c);
}
else
{
error = true;
break;
}
}
if (postfix.size() > 1 && postfix[postfix.size()-1] != DELIMITER)
postfix.push_back(DELIMITER);
while (!op.empty())
{
char c = op.top();
if (c == '(')
{
error = true;
break;
}
else
{
postfix.push_back(c);
postfix.push_back(DELIMITER);
op.pop();
}
}
return error ? "" : postfix;
}
结果:
((1+10)*3+5)/2 ==》》 1,10,+3,*,5,+,2,/,
求值
1. 扫描字符串,遇到数字,压入栈中,遇到操作符,从栈中弹出两个操作符,操作后,将结果再次压入栈中。
2. 注意除数为0的情况。
string getNext(string postfix)
{
static int begin = 0;
int end = postfix.find(DELIMITER, begin);
if (end == string::npos)
return "";
int start = begin;
begin = end + 1;
return postfix.substr(start, end - start);
}
int sum(string postfix)
{
stack<int> data;
if (postfix == "")
return 0;
string tmp;
while ( (tmp = getNext(postfix)) != "")
{
if (isOperator(tmp[0]))
{
int y = data.top(); data.pop();
int x = data.top(); data.pop();
int result;
char op = tmp[0];
if (op == '+')
result = x + y;
else if (op == '-')
result = x - y;
else if (op == '*')
result = x * y;
else
{
if (y == 0)
return 0;
result = x / y;
}
data.push(result);
}
else
{
int val = atoi(tmp.c_str());
data.push(val);
}
}
return data.top();
}
注意:在求值的过程中,处理除数为0的情况。