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

Posted

技术标签:

【中文标题】在 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

以上是关于在 JavaScript 中将中缀转换为前缀表示法的主要内容,如果未能解决你的问题,请参考以下文章

在 Scala 中将中缀转换为后缀表示法

在 Python 中为中缀表示法添加前缀表示法

可以仅使用队列将中缀表示法的字符串转换为前缀表示法吗? (考虑唯一的操作是 + 和 - 的情况)

算术表达式的前缀,中缀,后缀相互转换

7-20 表达式转换

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