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中的this变量的使用介绍
Oct 21 Javascript
javascript定义变量时加var与不加var的区别
Dec 22 Javascript
jquery移动点击的项目到列表最顶端的方法
Jun 24 Javascript
小巧强大的jquery layer弹窗弹层插件
Dec 06 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
Jun 08 Javascript
js学习心得_一个简单的动画库封装tween.js
Jul 14 Javascript
从对象列表中获取一个对象的方法,依据关键字和值
Sep 20 Javascript
vue cli使用绝对路径引用图片问题的解决
Dec 06 Javascript
微信小程序如何获取openid及用户信息
Jan 26 Javascript
javascript匿名函数中的'return function()'作用
Oct 15 Javascript
使用vue构建多页面应用的示例
Oct 22 Javascript
vue-cli —— 如何局部修改Element样式
Oct 22 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
phpMyAdmin自动登录和取消自动登录的配置方法
2014/05/12 PHP
PHP实现在线阅读PDF文件的方法
2015/06/17 PHP
WIFI万能钥匙密码查询接口实例
2015/09/28 PHP
PHP连接MYSQL数据库实例代码
2016/01/20 PHP
php 一维数组的循环遍历实现代码
2017/04/10 PHP
js表数据排序 sort table data
2009/02/18 Javascript
基于jQuery的为attr添加id title等效果的实现代码
2011/04/20 Javascript
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
js去空格技巧分别去字符串前后、左右空格
2013/10/21 Javascript
js获取IP地址的方法小结
2014/07/01 Javascript
AngularJS下对数组的对比分析
2016/08/24 Javascript
JS实现简单的tab切换选项卡效果
2016/09/21 Javascript
解析JavaScript实现DDoS攻击原理与保护措施
2016/12/26 Javascript
vue实现吸顶、锚点和滚动高亮按钮效果
2019/10/21 Javascript
[50:34]VGJ.T vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python爬取APP下载链接的实现方法
2016/09/30 Python
python基于pyDes库实现des加密的方法
2017/04/29 Python
python 设置文件编码格式的实现方法
2017/12/21 Python
python使用代理ip访问网站的实例
2018/05/07 Python
用Python分析3天破10亿的《我不是药神》到底神在哪?
2018/07/12 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
2020/02/14 Python
Pytorch对Himmelblau函数的优化详解
2020/02/29 Python
python实现ssh及sftp功能(实例代码)
2020/03/16 Python
用python实现一个简单的验证码
2020/12/09 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
ABOUT YOU匈牙利:500个最受欢迎的时尚品牌
2019/07/19 全球购物
澳洲网红粉泥面膜:Sand & Sky
2019/08/13 全球购物
查环查孕证明
2014/01/10 职场文书
社区优秀志愿者材料
2014/02/02 职场文书
公司业务员岗位职责
2014/03/18 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书
源码解读Spring-Integration执行过程
2021/06/11 Java/Android
go开发alertmanger实现钉钉报警
2021/07/16 Golang