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 学习笔记(八)javascript对象
Apr 12 Javascript
JavaScript获取文本框内选中文本的方法
Feb 20 Javascript
浅谈Sizzle的“编译原理”
Apr 14 Javascript
实现高性能JavaScript之执行与加载
Jan 30 Javascript
原生js仿jquery一些常用方法(必看篇)
Sep 20 Javascript
Vue2.0系列之过滤器的使用
Mar 01 Javascript
Angular4学习笔记router的简单使用
Mar 30 Javascript
微信小程序使用wxParse解析html的方法教程
Jul 06 Javascript
微信小程序获取位置展示地图并标注信息的实例代码
Sep 01 Javascript
angula中使用iframe点击后不执行变更检测的问题
May 10 Javascript
jQuery使用hide()、toggle()函数实现相机品牌展示隐藏功能
Jan 29 jQuery
vue elementUI批量上传文件
Apr 26 Vue.js
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
smarty实例教程
2006/11/19 PHP
PHP开发中常用的三个表单验证函数使用小结
2010/03/03 PHP
PHP递归删除目录几个代码实例
2014/04/21 PHP
Windows中使用计划任务自动执行PHP程序实例
2014/05/09 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
2017/11/12 PHP
PHP调用全国天气预报数据接口查询天气示例
2019/02/20 PHP
PHP压缩图片功能的介绍
2019/03/21 PHP
layui数据表格自定义每页条数limit设置
2019/10/26 PHP
使用AngularJS创建单页应用的编程指引
2015/06/19 Javascript
微信小程序 wxapp视图容器 view详解
2016/10/31 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
微信小程序左滑删除效果的实现代码
2017/02/20 Javascript
MUI 上拉刷新/下拉加载功能实例代码
2017/04/13 Javascript
[01:18:21]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
Python multiprocessing.Manager介绍和实例(进程间共享数据)
2014/11/21 Python
python清除指定目录内所有文件中script的方法
2015/06/30 Python
在python中实现强制关闭线程的示例
2019/01/22 Python
Python学习笔记之For循环用法详解
2019/08/14 Python
Python读入mnist二进制图像文件并显示实例
2020/04/24 Python
安装python依赖包psycopg2来调用postgresql的操作
2021/01/01 Python
html5 冒号分隔符对齐的实现
2019/07/31 HTML / CSS
英国奢侈品在线精品店:Hervia
2020/09/03 全球购物
Linux如何命名文件--使用文件名时应注意
2014/05/29 面试题
保安拾金不昧表扬信
2014/01/15 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
大学生入党积极分子党校学习思想汇报
2014/10/25 职场文书
整改落实情况汇报材料
2014/10/29 职场文书
2014年公务员个人工作总结
2014/11/22 职场文书
孔繁森观后感
2015/06/10 职场文书
企业安全生产规章制度
2015/08/06 职场文书
员工考勤管理制度
2015/08/06 职场文书
《珍珠鸟》教学反思
2016/02/16 职场文书
如何获取numpy array前N个最大值
2021/05/14 Python
JavaScript严格模式不支持八进制的问题讲解
2021/11/07 Javascript
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/06 PostgreSQL
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js