需求分析
模块图
类图
核心算法
中缀表达式转化为后缀表达式
规则:从左到右遍历中缀表达式(表达式运算符在两数字之间,比如(2+1)3)的每个数字和符号,若是数字就输出,即成为后缀表达式(表达式运算符在数字之后,不包含括号,比如2 1+3 )的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
转化为后缀表达式方便计算(所有的计算按运算符出现的顺序,严格从左向右进行,不再考虑运算符的优先规则。)。
规则分解
- 遇到操作数:直接输出(添加到后缀表达式中)
- 栈为空时,遇到运算符,直接入栈
- 遇到左括号:将其入栈
- 遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
- 遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
- 最终将栈中的元素依次出栈,输出。
现在按规则将中缀表达式(2+1)*3转化为后缀表达式
首先是左括号,进栈
( |
然后是数字2 直接输出 2
接着是+号,进栈
+ |
( |
然后是数字1 直接输出在2后面 2 1
然后遇到右括号,栈中所有元素出栈,输出加号,左括号不输出 2 1 +
接着*号,进栈
* |
然后是数字3 直接输出 2 1 + 3
表达式结束,栈中元素出栈 输出号 2 1 + 3
代码
QStack<QString> stack;
QString temp;//数字输出
QStringList list;//全部输出
while(!expression.isEmpty())
{
if(expression.startsWith('+')||expression.startsWith('-')||expression.startsWith('*')||expression.startsWith('/')||expression.startsWith('(')||expression.startsWith(')'))
{
//遇到运算符及左右括号,可能进栈,出栈
if(!temp.isEmpty())
{
list.append(temp);
temp.clear();
}
//+-)优先级高于或等于其它运算符及左括号,遇到则使栈中元素弹出
if(expression.startsWith('+')||expression.startsWith('-')||expression.startsWith(')'))
{
while(!stack.isEmpty())
{
if(stack.top()==QString('('))
{
//栈顶为左括号,遇到右括号,直接让左括号出栈,不输出
if(expression.startsWith(')'))
{
stack.pop();
}
break;
}
else
{
//将栈中元素输出,直到栈顶为左括号
list.append(stack.pop());
}
}
}
if(expression.startsWith(')'))
expression.remove(0,1);