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实例教程(19) 使用HoTMetal(4)
Dec 23 Javascript
javascript里的条件判断
Feb 27 Javascript
如何简单地用YUI做JavaScript动画
Mar 10 Javascript
JQuery 前台切换网站的样式实现
Jun 22 Javascript
JQuery的一些小应用收集
Mar 27 Javascript
监控 url fragment变化的js代码
Apr 19 Javascript
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
Jun 21 Javascript
vue2.0构建单页应用最佳实战
Apr 01 Javascript
vue Element-ui input 远程搜索与修改建议显示模版的示例代码
Oct 19 Javascript
详解RequireJs官方使用教程
Oct 31 Javascript
微信小程序云开发修改云数据库中的数据方法
May 18 Javascript
Vue使用Proxy监听所有接口状态的方法实现
Jun 07 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
把从SQL中取出的数据转化成XMl格式
2006/10/09 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
PHP入门教程之操作符与控制结构流程详解
2016/09/09 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
Laravel 自带的Auth验证登录方法
2019/09/30 PHP
phpcmsv9.0任意文件上传漏洞解析
2020/10/20 PHP
JavaScript 学习笔记(七)字符串的连接
2009/12/31 Javascript
6个DIV 135或246间隔一秒轮番显示效果
2010/07/24 Javascript
jquery滚动条插件jScrollPane的使用介绍
2013/11/08 Javascript
Bootstrap每天必学之js插件
2015/11/30 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
2016/04/29 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
JS 实现导航菜单中的二级下拉菜单的几种方式
2016/10/31 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
Angular使用动态加载组件方法实现Dialog的示例
2018/05/11 Javascript
浅谈react性能优化的方法
2018/09/05 Javascript
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
2016/07/04 Python
python爬虫获取淘宝天猫商品详细参数
2020/06/23 Python
Python内置函数reversed()用法分析
2018/03/20 Python
5分钟 Pipenv 上手指南
2018/12/20 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
keras中的卷积层&amp;池化层的用法
2020/05/22 Python
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
Burberry英国官网:英国标志性奢侈品牌
2017/03/29 全球购物
自荐信模版
2013/10/24 职场文书
技术经理的自我评价范文
2013/12/03 职场文书
银行学习十八大感想
2014/01/11 职场文书
2015年第31个教师节致辞
2015/07/31 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
导游词之镜泊湖
2019/12/09 职场文书
如何使用pdb进行Python调试
2021/06/30 Python