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 相关文章推荐
javascript实现的listview效果
Apr 28 Javascript
javascript 特殊字符串
Feb 25 Javascript
web前端开发也需要日志
Dec 09 Javascript
JS代码同步文本框内容的实例方法
Jul 12 Javascript
JavaScript html5 canvas画布中删除一个块区域的方法
Jan 26 Javascript
总结JavaScript三种数据存储方式之间的区别
May 03 Javascript
浅析JSONP技术原理及实现
Jun 08 Javascript
H5移动端适配 Flexible方案
Oct 24 Javascript
JavaScript如何获取到导航条中HTTP信息
Oct 10 Javascript
VueJS 组件参数名命名与组件属性转化问题
Dec 03 Javascript
React服务端渲染原理解析与实践
Mar 04 Javascript
React forwardRef的使用方法及注意点
Jun 13 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获取数组中重复数据的两种方法
2013/06/28 PHP
php 字符串压缩方法比较示例
2014/01/23 PHP
Laravel5权限管理方法详解
2016/07/26 PHP
PHP页面静态化――纯静态与伪静态用法详解
2020/06/05 PHP
js调用flash的效果代码
2008/04/26 Javascript
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
jQuery 源码分析笔记(4) Ready函数
2011/06/02 Javascript
JavaScript判断DOM何时加载完毕的技巧
2012/11/11 Javascript
js实现同一页面可多次调用的图片幻灯切换效果
2015/02/28 Javascript
Jquery实现textarea根据文本内容自适应高度
2015/04/03 Javascript
Jquery元素追加和删除的实现方法
2016/05/24 Javascript
js自定义弹框插件的封装
2020/08/24 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
NodeJS服务器实现gzip压缩的示例代码
2018/10/12 NodeJs
layui导出所有数据的例子
2019/09/10 Javascript
vue基于better-scroll实现左右联动滑动页面
2020/06/30 Javascript
vue插件--仿微信小程序showModel实现模态提示窗功能
2020/08/19 Javascript
Python yield 小结和实例
2014/04/25 Python
python计算圆周率pi的方法
2015/07/11 Python
python logging 日志轮转文件不删除问题的解决方法
2016/08/02 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
Python单元测试实例详解
2018/05/25 Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
2019/06/21 Python
windows下Python安装、使用教程和Notepad++的使用教程
2019/10/06 Python
详解mac python+selenium+Chrome 简单案例
2019/11/08 Python
Python爬虫爬取糗事百科段子实例分享
2020/07/31 Python
HTML5 Web Workers之网站也能多线程的实现
2013/04/24 HTML / CSS
HTML5高仿微信聊天、微信聊天表情|对话框|编辑器功能
2018/04/23 HTML / CSS
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
Laura官网:加拿大女性的顶级时尚目的地
2019/09/20 全球购物
工程力学硕士生的自我评价范文
2013/11/16 职场文书
元旦红领巾广播稿
2014/02/19 职场文书
经典婚礼主持开场白
2014/03/13 职场文书
2014年校务公开工作总结
2014/12/18 职场文书
python 爬取豆瓣网页的示例
2021/04/13 Python