JavaScript数据结构中栈的应用之表达式求值问题详解


Posted in Javascript onApril 11, 2017

本文实例讲述了JavaScript数据结构中栈的应用之表达式求值问题。分享给大家供大家参考,具体如下:

下面来谈一个比较经典的表达式求值问题,这个问题主要是设计到操作符的优先级。我们通常看到的表达式都是中缀表达式,存在很多优先级差别,而后缀表达式则没有这些优先级问题。下面先看看两种表达式的区别。

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

从中缀表达式转换到后缀表示式是很难实现的,我们这里可以通过栈的思想来实现。下面进行详细的介绍是什么样的思想:

在对一个中缀表示式进行转换的时候,遇到非操作符的字符则直接保存到后缀表示式的存储空间中。

遇到(,则压入栈,只有遇到对应的)才能被弹出。
遇到),就将(之前的操作符全部弹出,并保存到存储空间。
遇到*和/这样优先级高的,就判断栈中的操作符优先级是否低于当前操作符。
如果栈中的遇到的低,则将遇到的继续入栈;如果栈中的高,则将栈中的出栈,遇到的入栈。
最后,当字符串遍历完成,依次弹出操作符,保存到存储空间。

为了方便理解,将上面的例子再次讲解。a*b+c*d-e/f

首先是ab被保存到了存储空间,然后*入栈。现在栈中只有*。
遇到+之后,由于*比+优先级高,所以*出栈,+入栈,这样存储空间变为ab*,栈中变为+。
再时候遇到c,存储空间变为ab*c,栈中还是+。
接下来遇到*和d,由于+比*低,所以*继续入栈,栈中表为了+*,存储空间为ab*cd。
之后遇到-,由于*比-高,所以+*出栈,-入栈,存储空间变为ab*cd*+
……后面不用解释了,悟性再低也应该会了。

下面我们用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>

当然,以上程序还存在一点bug,但是思想应该就是这样子的。

下面,我们将讲解如何通过后缀表达式计算出表达式的结果。

那么,我们将中缀表达式转化为后缀表达式后,如何继续计算呢?还是以这个例子为例。

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

基本思路如下:

遍历后缀表达式,遇到非操作符的字符则直接进栈,遇到操作符则出栈两个元素,进行对应操作,然后将得到的结果再次入栈。依次直到遍历完成,此处栈中保存的值就是当前表达式的值。

实现的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 相关文章推荐
使用Modello编写JavaScript类
Dec 22 Javascript
JQuery学习笔录 简单的JQuery
Apr 09 Javascript
jquery及原生js获取select下拉框选中的值示例
Oct 25 Javascript
基于jquery异步传输json数据格式实例代码
Nov 23 Javascript
js实现简单选项卡与自动切换效果的方法
Apr 10 Javascript
jQuery自定义滚动条完整实例
Jan 08 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
May 16 Javascript
bootstrap常用组件之头部导航实现代码
Apr 20 Javascript
.vue文件 加scoped 样式不起作用的解决方法
May 28 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
Oct 26 Javascript
JavaScript字符串处理常见操作方法小结
Nov 15 Javascript
微信小程序中网络请求缓存的解决方法
Dec 29 Javascript
js 获取今天以及过去日期
Apr 11 #Javascript
javascript数据结构中栈的应用之符号平衡问题
Apr 11 #Javascript
javascript编程实现栈的方法详解【经典数据结构】
Apr 11 #Javascript
Bootstrap 3浏览器兼容性问题及解决方案
Apr 11 #Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
Apr 11 #Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
Apr 11 #Javascript
基于vuejs实现一个todolist项目
Apr 11 #Javascript
You might like
PHP5.0对象模型探索之抽象方法和抽象类
2006/09/05 PHP
基于curl数据采集之单页面并行采集函数get_htmls的使用
2013/04/28 PHP
destoon实现调用自增数字从1开始的方法
2014/08/21 PHP
thinkPHP实现表单自动验证
2014/12/24 PHP
PHP学习笔记(一):基本语法之标记、空白、和注释
2015/04/17 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
2019/10/11 PHP
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
2013/01/27 Javascript
JQuery1.8 判断元素是否绑定事件的方法
2014/07/10 Javascript
jQuery实现视频作为全屏幕背景
2014/12/18 Javascript
JavaScript数组去重的3种方法和代码实例
2015/07/01 Javascript
jQuery实现动画效果circle实例
2015/08/06 Javascript
全系IE支持Bootstrap的解决方法
2015/10/19 Javascript
js基础知识(公有方法、私有方法、特权方法)
2015/11/06 Javascript
基于JavaScript实现高德地图和百度地图提取行政区边界经纬度坐标
2016/01/22 Javascript
jQuery封装的屏幕居中提示信息代码
2016/06/08 Javascript
Javascript获取background属性中url的值
2016/10/17 Javascript
jQuery 插件封装的方法
2016/11/16 Javascript
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
vue init失败简单解决方法(终极版)
2017/12/22 Javascript
vue中v-text / v-html使用实例代码详解
2019/04/02 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
Python优先队列实现方法示例
2017/09/21 Python
浅析python参数的知识点
2018/12/10 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
python3操作注册表的方法(Url protocol)
2020/02/05 Python
Nike西班牙官方网站:Nike.com (ES)
2017/10/30 全球购物
size?法国官网:英国伦敦的球鞋精品店
2020/03/15 全球购物
毕业设计计划书
2014/01/09 职场文书
聚美优品广告词改编
2014/03/14 职场文书
暑期培训班策划方案
2014/08/26 职场文书
2014年综合治理工作总结
2014/11/20 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
2014年乡镇纪委工作总结
2014/12/19 职场文书
2015年英语教研组工作总结
2015/05/23 职场文书
运动会闭幕式主持词
2015/07/01 职场文书