逆波兰数:逆波兰数由两部分组成(操作数,操作符)——是波兰表达式的一种,即操作符在操作数的后面。
形式:A+B*C-D = ABC*D-;
(A+B)*C-D = AB+C*D-;
既然我们知道了,后缀表达式那我们表达式是唯一的吗?我们来看一组数据:
例如:(A+B)*C-D 和 C*(A+B)-D;
很显然第二个的表达式为:C*AB+D-;虽然对最后的结果无影响,但我们需要知道逆波兰的多样性。
注意事项:
1、如果出现1+23 = 123+,该如何判断它的数值呢?
可以利用分割符来进行很好的辅助性理解,例如1+23 = 1#23#+,这样可以完美的解决此问题。
2、存在括号的时候该如何处理?
其一:是‘(’直接压入,‘)’时,将两者之间的运算符弹出,压入后缀表达式。
其二:遇到‘(’开辟一个新的运算符栈,‘)’时,当前栈内运算符弹出,压入后缀表达式。
算法:
1、中缀表达式——逆波兰表达式的转变。
- 准备一个栈一个链表,链表用来存操作数,栈用来存操作符。
- 如果为操作数,我们继续判断它的下一位是否也为操作数,是——则继续压入,否——压入分隔符(“#”)。同时判断字符栈中,是否为“*”,“/”,字符弹出,压入数值链表。
- 如果为操作符,直接压入字符栈。
- 如果‘(’,重新开辟一个新字符栈,其它操作相同。
- 如果‘ )’,将当前字符栈内部的字符逐个弹出,压入数值链表。
2、逆波兰求值。
- 准备一个栈,用来逐个求当前值。
- 依次取出数值链表的第一个值。
- 根据加减乘除运算做出相应的操作,即取出当前栈的前两个值,做运算符操作。
- 如果是操作数,我们继续判断它的下一位是否也为操作数,是——n*10+char-‘0’,否——压入栈中;
- 最后的到栈顶元素,即为运算后的值。
核心代码:
1、中缀表达式——逆波兰表达式的转变。
bool is_char(char c)//判断是否为操作符
{
return c == '-' || c == '+' || c == '*' || c == '/';
}
void change()//表达式的转化
{
char c;
int i = 0, j = 0;//i遍历输入的字符,j不同层数的字符栈
while ((c = original[i++]) != '