如何在程序中将中缀表达式转换为后缀表达式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在程序中将中缀表达式转换为后缀表达式相关的知识,希望对你有一定的参考价值。

中缀表达式转换为后缀表达式的方法
a + b * c - (d + e)
按照运算符的优先级对所有的运算单位加括号。
((a + (b * c)) - (d + e))
转换中缀与后缀表达式后缀:把运算符号移动到对应的括号后面。
((a (b c) * ) + (d e) + ) -
把括号去掉,记得到了后缀表达式
a b c * + d e + -
可以发现,后缀表达式是不需要括号来调整运算优先级的。
参考技术A 中缀表达式,是正常书写的方式,如公式A+B*C
后缀表达式也称(逆波兰表达式),对中缀的表示为ABC*+

转换方法,对公式字符串进行逐位判断。遇到公式中的变量直接输出,运行符入栈。
入栈时,比较栈顶运算符与入栈运算符的高低,再行出栈和入栈。

举例:
公式:A+B*C
1,输出A
2,入栈+(栈为空)
3,输出B
4,*入栈(*与栈顶元素+比较,如果栈顶优先级高,则先输出栈顶元素,否则入栈当前运算符)
5,输出C
6,出栈*
7,出栈+

在 JavaScript 中将中缀转换为前缀表示法

【中文标题】在 JavaScript 中将中缀转换为前缀表示法【英文标题】:Converting Infix to prefix notation in JavaScript 【发布时间】:2019-12-02 02:03:54 【问题描述】:

(我过去确实问过类似的问题,但文档有误,所以这是过去问题的正确版本)

请在 JavaScript 中帮助我:我正在编写的程序是一个以前缀表示法接收表达式并以中缀表示法输出相同表达式的程序。这个程序背后的想法如下:

如果用户输入 + 1 2,则预期输出为 1 + 2。所有有效符号为 +、-、*、/ 和 %。用户可以输入的数字数量应该是无限的(例如,如果我输入 + + + + + + + + + 1 2 3 4 5 6 7 8 9 10,程序应该返回 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)。

有人可以帮我填写循环的注释部分,如果您认为有更好的方法来解决这个问题,我愿意接受!

function infix(input) 
  var x = input.split(''); // splits each variable and stores it in an array
  var output = [];
  var final = " "; // will be used to store our infix expression
  for (var i = 0; i < x.length; i++) 
    //if x[i] is any of the following : "+, -, *, /, or %" , store it in array output at index 0
    //else if x[i] is a number : store it in an index of array output that is >= 1

  
  for (var j = 0; j < output.length; j++) 
    var final = x[0] + x[j];
  
  console.log(final);


infix("1 + 2 + 3") // should output "+ + 1 2 3"
infix("1 - 2 % 3 + 1 * 4") // should output "- % + * 1 2 3 1 4"

【问题讨论】:

您的问题描述了将前缀转换为中缀,但是您的代码块似乎想要将中缀转换为前缀。你要哪个? 是的,我不知道该怎么做,这就是为什么我把它留给任何其他解决方案。如果你有,请分享!为了清楚起见,程序应该采用中缀形式并输出该表达式的前缀版本。 当您说if the user enters + 1 2 the expected output is 1 + 2 时,您的意思是相反的吗?即将1 + 2 转换为+ 1 2。如果是这样,请更新您的问题。 【参考方案1】:

您的代码大部分都在那里。

您的程序的主要逻辑需要将您的输入字符串分成两个部分(数组)。一个用于符号/operands,另一个用于numbers。检查x[i] 是否为“+, -, ...”将允许我们检查当前符号是否为操作数,这是一个好的开始。但是,我们不想将它存储在 output 数组的索引 0 处。如果你这样做了,那么所有的符号都会以相反的顺序输入(这不是你想要的)。相反,您可以将符号添加到数组的末尾。在下面的代码 sn-p 中,我已将所有符号推入 operands 数组。

那么,我们如何检查x[i] 是否是一个符号?一种方法是针对每个符号检查x[i],如下所示:

if(x[i] === "+" || x[i] === "-" || ... ) 
  operands.push(x[i]); // add the symbol to the end of the array  

或者,您可以使用.includes() 更简洁地编写此代码,这样就无需多个||

var symbols = ['+', '-', '*', '/', '%'];
...
if(symbols.includes(x[i])) 
  operands.push(x[i]); 

如果当前字符 (x[i]) 不是符号,那么它必须是数字(因为我们按空格分隔)。因此,您可以添加一个else,并将当前字符推入numbers 数组。

遍历所有字符后,您将获得一个操作数数组,按照它们在输入字符串中出现的顺序,以及一个数字数组,按照它们在输入字符串中出现的顺序。我们的最后一步是将operandsnumbers 数组转换为字符串,其中这些数组中的每个元素用空格分隔。最简单的方法是使用.join() 方法,该方法会将数组中的每个元素连接成一个字符串,并通过您提供的参数分隔每个元素。

通过所有这些,您可以获得所需的输出:

function infix(input) 
  var x = input.split(' '); // splits each character and stores it in an array
  var operands = [];
  var numbers = [];
  var symbols = ['+', '-', '/', '*', '%'];

  for (var i = 0; i < x.length; i++) 
    if(symbols.includes(x[i])) 
      operands.push(x[i]);
     else 
      numbers.push(x[i]);
    
  
  var final = operands.join(' ') +' ' +numbers.join(' ');
  return final;


console.log(infix("1 + 2 + 3")); // "+ + 1 2 3"
console.log(infix("1 - 2 % 3 + 1 * 4")); // "- % + * 1 2 3 1 4"

或者,您可以更简洁地使用.match() 方法获取非数字(或空格)字符并使用另一个方法获取数字字符:

const infix = input =>
   [...input.match(/[^\d\s]/g), ...input.match(/\d+/g)].join(' ');

console.log(infix("1 + 2 + 3")); // "+ + 1 2 3"
console.log(infix("1 - 2 % 3 + 1 * 4")); // "- % + * 1 2 3 1 4"

【讨论】:

您的函数将'1 + 4 * 2 + 3' 转换为'+ * + 1 4 2 3',其计算结果为13,但中缀符号计算结果为12。对吗? @customcommander 嗨,我以 OP 为例,而不是技术上正确的形式。似乎 OP 只是想提取运算符并将它们放在等式的前面。例如,在 OP 示例中,他们希望 1 - 2 % 3 + 1 * 4 成为 - % + * 1 2 3 1 4。两者都评估为两个不同的结果,中缀为3,前缀为-4

以上是关于如何在程序中将中缀表达式转换为后缀表达式的主要内容,如果未能解决你的问题,请参考以下文章

中缀表达式如何转换为前后缀表达式?

将中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式(1042)

PTA-7-20 表达式转换(中缀转后缀,带括号,负数,小数转换)

中缀表达式转换前\后缀表达式的总结

将中缀表达式转换成后缀表达式