在逆波兰表达式的博客中已经说过了中缀表达式和后归表达式的区别了,所以接下来直奔主题。
例子:中缀表达式:(1+2)*5+10/3
后缀表达式:1 2 + 5 * 10 3 / +
如果将上述的中缀表达式转换为后缀表达式?
转换原则:
1.当读取到一个数字的时候直接将其输出,不进行压栈,如果遇见操作符则不输出将其进行压栈,左括号也要压栈
2.如果读取遇到了右括号表示括号匹配完毕,不将右括号压栈,而是将栈中的元素以此弹栈输出,直到遇见左括号结束(注意这里 的左括号不输出,但是出栈了)
3.如果读取到了+ 或者-,先判断栈是否为空,如果为空则将其进行压栈,如果不为空,则将栈中的元素弹栈判断是否为左括号,如果是继续将左括号进行压栈,如果不是则继续输出直到遇见了左括号停止。
4.读取结束后将栈中所有内容弹出并输出便得到正确结果
上图看着可能有点乱,不过你按照5+(4-3)*4+10/5从左往右看,上面的输出是逐个输出的,不过这个图是我最后分析完所以就输出了所有的结果,下面的栈结构图是进栈出栈的几个状态图,为了方便看我才画成四个的,其实只需要在一个栈上进行进栈出栈操作就可以了,接下来贴上代码
代码如下:
void test()
{
char input;
char e;
stack stack2;
Initstack(&stack2);
printf("请输入你要计算的中缀表达式,按#结束");
scanf("%c", &input);
while (input != '#')
{
while (input>='0'&&input<='9')//判断是否读取到数字
{
printf("%c", input);//是数字将其输出
scanf("%c", &input);//继续读取
if (input< '0'||input>'9')//继续判断是否为数字,如果不是输出空格
{
printf(" ");
break;
}
}
if ('*' == input || '/' == input || '(' == input)//判断读取是否为* / ( 如果是进行压栈
{
pushstack(&stack2, input);
}
else if ('+' == input || '-' == input)//判断是否为+ -
{
if (!getlen(stack2))//如果栈为空进行压栈
{
pushstack(&stack2, input);
}
else // 因为牵扯到运算符的优先级,所以如果+ -前面有元素在栈中的元素弹出输出直到遇到(
{
do
{
popstack(&stack2, &e);//
if ('(' == e)//判断是否为(
{
pushstack(&stack2, e);
}
else//不是(将其输出
{
printf("%c ", e);
}
} while (getlen(stack2) && '(' != e);//循环输出的条件
pushstack(&stack2, input);//然后将+ -入栈
}
}
else if (')' == input)//如果读取到)将栈中的元素出栈输出直到遇见(
{
popstack(&stack2, &e);
while ('(' != e)
{
printf("%c ", e);
popstack(&stack2, &e);
}
}
else if (input == '#')//如果读取到#这个结束
{
break;
}
else
{
printf("输入错误\n");
return;
}
scanf("%c", &input);
}
while (getlen(stack2))
{
popstack(&stack2, &e);
printf("%c ", e);
}
}
测试结果:
有什么问题,欢迎提出交流!