JavaScript栈应用:中缀转后缀表达式及求值实现

作者:拾光

时间:2026-10-22

浏览:576

本文详解JavaScript中栈在表达式求值中的应用。通过栈结构处理操作符优先级,将中缀表达式转换为后缀表达式,并遍历后缀式进行数值计算。文章提供完整代码示例,解析入栈出栈逻辑及边界处理,适用于数据结构学习与算法实现参考。

文章目录

栈在表达式求值中的应用概述

本文通过具体实例,深入解析JavaScript中栈数据结构在表达式求值问题上的应用,旨在为读者提供清晰的参考与学习思路。

接下来探讨一个经典的表达式求值场景,其核心难点在于操作符优先级的处理。日常书写多为中缀表达式,存在复杂的优先级规则;而后缀表达式则消除了这些优先级歧义。下文将对比两种表达式的差异。

中缀表达式示例:a*b+c*d-e/f 后缀表达式示例:ab*cd*+ef/-

中缀表达式转后缀表达式的栈逻辑

从中缀表达式转换为后缀形式具有一定难度,但利用栈的数据结构特性可以高效实现。下面详细阐述这一转换背后的核心逻辑。

在转换过程中,若遇到非操作符字符,直接将其追加到后缀表达式的存储结果中。

当遇到左括号“(”时,将其压入栈内,仅当匹配到右括号“)”时才弹出。 遇到右括号“)”时,将栈顶至左括号“(”之间的所有操作符依次弹出,并追加到存储结果中。 对于“*”和“/”等高优先级操作符,需判断栈顶操作符的优先级是否低于当前操作符。 若栈顶优先级较低,则当前操作符直接入栈;若栈顶优先级较高或相等,则将栈顶操作符弹出并加入结果,随后当前操作符入栈。 字符串遍历结束后,将栈内剩余的操作符依次弹出,追加至存储结果中,完成转换。

为便于理解,以上述例子再次演示转换过程:a*b+c*d-e/f

初始阶段,“a”和“b”被存入结果区,“*”压入栈,此时栈内仅含“*”。 遇到“+”时,因“*”优先级高于“+”,故“*”弹出至结果区,“+”入栈,结果区变为“ab*”,栈内变为“+”。 随后遇到“c”,直接存入结果区,结果区更新为“ab*c”,栈内仍为“+”。 接着遇到“*”和“d”,因栈顶“+”优先级低于“*”,故“*”入栈,栈内变为“+*” ,结果区更新为“ab*cd”。 再遇到“-”,因栈顶“*”优先级高于“-”,故“*”和“+”依次弹出至结果区,“-”入栈,结果区变为“ab*cd*+”。 后续步骤逻辑一致,不再赘述。

JavaScript转换代码实现

下面使用JavaScript代码实现上述转换逻辑。


<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
 </head>
 <body>
<script type="text/javascript">
 function midTOLast(a){
  var a_len=a.length;
  var myArray=new Array();
  b='';
  for(var i=0;i<a_len;i++){
   switch (a[i]){
    case '(':
    {
     myArray.push(a[i]);
     break;
    }
    case ')'://如果是)则将栈中左括号之前的对象弹出
    {
     if(myArray.length==0){
      return false;
     }
     temp=myArray.pop();//非空,弹出对象
     while(temp!='('){//只要不是左括号,则全部弹出
      b+=temp;//并输出到后缀表达式中
      if(myArray.length==0){//保证栈为空
       break;
      }
      temp=myArray.pop();
     }
     break;
    }
    case '*':
    case '/':
    {
     if(myArray.length==0){//如果栈为空则直接入栈
      myArray.push(a[i]);
     }else{
      temp=myArray[myArray.length-1];
      if(temp=='+'||temp=='-'){//如果遇到高的,则遇到的继续入栈
       myArray.push(a[i]);//遇到的入栈
      }
     }
     break;
    }
    case '+':
    case '-':
    {
     if(myArray.length==0){//如果栈为空则直接入栈
      myArray.push(a[i]);
     }else{
      temp=myArray[myArray.length-1];
      if(temp=='/'||temp=='*'){//如果遇到低的,则栈中的出栈,遇到的入栈
       while(myArray.length!=0){
        temp=myArray.pop();//栈中的出栈
        b+=temp;//保存到存储空间
       }
       myArray.push(a[i]);//遇到的入栈
      }
     }
     break;
    }
    default:
    {
     b+=a[i];
     break;
    }
   }
  }
  //最后将栈中剩下的操作符输出
  while(myArray.length!=0){
   temp=myArray.pop();
   b+=temp;
  }
  return true;
 }
 var x="a*b+c*d-e/f";
 midTOLast(x);
 alert(b);//ab*cd*+ef/-
</script>
 </body>
</html>

需注意,上述程序可能存在细微缺陷,但核心思想已清晰呈现。

后缀表达式的数值计算原理

接下来讲解如何基于后缀表达式计算最终数值结果。

将中缀表达式转化为后缀表达式后,如何进一步计算?仍以该例子为例说明。

中缀表达式:a*b+c*d-e/f 后缀表达式:ab*cd*+ef/-

基本计算思路如下:

遍历后缀表达式字符串,若遇到非操作符字符(如数字或变量),直接压入栈中;若遇到操作符,则从栈中弹出两个元素进行相应运算,并将计算结果重新压入栈内。重复此过程直至遍历结束,此时栈中剩余的唯一值即为表达式的最终结果。

JavaScript计算代码实现

对应的JavaScript实现代码如下:


<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
 </head>
 <body>
<script type="text/javascript">
 function getValue(a){
  var a_len=a.length,
   myArray=new Array();
   for(var i=0;i<a_len;i++){
    switch (a[i])
    {//遇到数值则直接入栈
     case '0':
     case '1':
     case '2':
     case '3':
     case '4':
     case '5':
     case '6':
     case '7':
     case '8':
     case '9':
     {
      myArray.push(a[i]);
      break;
     }
     case '+':
     {//遇到操作符则出栈两个元素进行对应操作
      temp=myArray.pop()+myArray.pop();
      myArray.push(temp);//再将结果入栈
      temp=null;
      break;
     }
     case '-':
     {
      s=myArray.pop();
      temp=myArray.pop()-s;
      myArray.push(temp);
      s=null;temp=null;
      break;
     }
     case '*':
     {
      temp=myArray.pop()*myArray.pop();
      myArray.push(temp);//再将结果入栈
      temp=null;
      break;
     }
     case '/':
     {
      s=myArray.pop();
      temp=myArray.pop()/s;
      myArray.push(temp);
      s=null;temp=null;
      break;
     }
    }
   }
   return myArray.pop();//算出结果
 }
 var a="12*34*+36/-";//1*2+3*4-3/6
 var b=getValue(a);//13.5
 alert(b);
</script>
 </body>
</html>

栈的应用场景广泛,还包括进制转换、行编辑程序处理、迷宫求解等,此处不再逐一展开。

更多关于JavaScript相关技术感兴趣的读者,可查阅本站专题:《JavaScript数据结构与算法技巧总结》、《JavaScript数学运算用法总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》。

希望本文所述内容能对您的JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章