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 相关文章推荐
一个JS的日期格式化算法示例
Jul 31 Javascript
JavaScript函数详解
Nov 17 Javascript
JSON与XML优缺点对比分析
Jul 17 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
Feb 21 Javascript
JS简单实现获取元素的封装操作示例
Apr 07 Javascript
在Vue组件化中利用axios处理ajax请求的使用方法
Aug 25 Javascript
JS实现点击下拉菜单把选择的内容同步到input输入框内的实例
Jan 23 Javascript
使用Angular 6创建各种动画效果的方法
Oct 10 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
Jun 07 Javascript
js实现图片跟随鼠标移动效果
Oct 16 Javascript
js实现前端界面导航栏下拉列表
Aug 27 Javascript
TS 类型收窄教程示例详解
Sep 23 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
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
Linux下ZendOptimizer的安装与配置方法
2007/04/12 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
深入php之规范编程命名小结
2013/05/15 PHP
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
使用php-timeit估计php函数的执行时间
2015/09/06 PHP
javascript温习的一些笔记 基础常用知识小结
2011/06/22 Javascript
javascript动画对象支持加速、减速、缓入、缓出的实现代码
2012/09/30 Javascript
JS简单实现动画弹出层效果
2015/05/05 Javascript
javascript针对cookie的基本操作实例详解
2015/11/30 Javascript
详解Vue-基本标签和自定义控件
2017/03/24 Javascript
JS利用正则表达式实现简单的密码强弱判断实例
2017/06/16 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
在vue中读取本地Json文件的方法
2018/09/06 Javascript
Vue.js 使用v-cloak后仍显示变量的解决方法
2018/11/19 Javascript
实现elementUI表单的全局验证的方法步骤
2019/04/29 Javascript
[05:09]2016国际邀请赛中国区预选赛淘汰赛首日精彩回顾
2016/06/29 DOTA
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
使用python实现tcp自动重连
2017/07/02 Python
python决策树之CART分类回归树详解
2017/12/20 Python
TensorFlow中权重的随机初始化的方法
2018/02/11 Python
Django自定义过滤器定义与用法示例
2018/03/22 Python
Python实现统计给定列表中指定数字出现次数的方法
2018/04/11 Python
python用opencv批量截取图像指定区域的方法
2019/01/24 Python
python opencv 读取本地视频文件 修改ffmpeg的方法
2019/01/26 Python
用python做游戏的细节详解
2019/06/25 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
申请任职学生会干部自荐书范文
2014/02/13 职场文书
总账会计岗位职责
2014/03/13 职场文书
青岛导游词
2015/02/12 职场文书
安全员岗位职责范本
2015/04/11 职场文书
2015学校年度工作总结
2015/05/11 职场文书
一波干货,会议主持词开场白范文
2019/05/06 职场文书
Python异常类型以及处理方法汇总
2021/06/05 Python
分析并发编程之LongAdder原理
2021/06/29 Java/Android