RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript
1、利用栈(Stack)来存储操作数和操作符;
2、包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点;
2.1、将输入字符串转为数组;
2.2、对转换来的字符进行遍历;创建一个数组,用来给存储转换为后缀表达式的字符;创建一个栈,用来存储操作符;
2.3、通过正则来过滤,为数字的则放在数组中,其他的则放在栈中;
2.4、接下来是最麻烦的操作符判断,我做的这个比较简单,如果再复杂些,我这个可能还要进行扩展或优化;
2.5、对操作符的判断按照其优先级来,首先是括号,有‘(’,直接压人,等到有‘)’的时候再一个个的将括号内的操作符进行弹出,如果里面有两个以上,则要先弹
靠近‘(’的;
2.6、然后是乘除。这里,我将乘除的弹栈放在了它的入栈前面,两则并不冲突,也不会对其他操作符有影响,因为它在添加数字的时候,就把乘或除弹出来了添加到数组;
2.7、上一个乘或除已经被弹出去了,数字添加后,如果后面字符是乘或除,则就直接入栈。(比如测试testing中的第一字符串,有连个两个乘);
2,8、最后是加减。首先,如果是空栈,直接入栈,如果不是空栈,则判断栈顶是否有‘(’,有则直接入栈,如果栈顶这些情况都没有(前面已经经乘除考虑了,这里就无需考虑了),
则说明栈内都是加或减,这时可以
将栈顶元素弹栈,并添加到数组中,再将当前操作符入栈。
3、包含后缀表达式的计算方式;
4、利用主函数main来调用;
5、cmd测试。
1 function Stack(){ 2 this.store = []; 3 this.top = 0; 4 this.push = push; 5 this.pop = pop; 6 } 7 8 function push(ele){ 9 this.store[this.top++] = ele; 10 } 11 12 function pop(){ 13 var top = --this.top; 14 if(top >= 0){ 15 var val = this.store[top]; 16 //-----------------务必删除弹出栈的值原来的空间---------------------------- 17 this.store.splice(this.top,1); 18 return val; 19 }else{ 20 return 'It\' Ending !'; 21 } 22 23 24 } 25 //----------------中缀表达式转后缀表达式----------------------------------- 26 function normalChar(normalC){ 27 normalC = normalC.split(' '); 28 var arr = []; 29 var ls = new Stack(); 30 var reg = /\d/; 31 32 for(var i=0; i<normalC.length; i++){ 33 if(reg.test(normalC[i])){ 34 arr.push(normalC[i]); 35 36 } 37 if(normalC[i] == '('){ 38 ls.push(normalC[i]); 39 } 40 else if(normalC[i] == ')'){ 41 while(ls.store[ls.top-1] != '('){ 42 arr.push(ls.pop()); 43 } 44 ls.pop(); 45 } 46 //-----------------此处是在添加数字的时候进行的,不会和其他操作符发生冲突-- 47 else if(ls.store[ls.top-1] == '*' || ls.store[ls.top-1] =='/'){ 48 arr.push(ls.pop()); 49 } 50 51 else if(normalC[i] == '*' || normalC[i] =='/'){ 52 ls.push(normalC[i]); 53 54 } 55 else if(normalC[i] == '+' || normalC[i] =='-'){ 56 if(ls.top == 0){ 57 ls.push(normalC[i]); 58 } 59 else if(ls.top > 0){ 60 if(ls.store[ls.top-1] == '('){ 61 ls.push(normalC[i]); 62 }else{ 63 arr.push(ls.pop()); 64 ls.push(normalC[i]); 65 } 66 } 67 68 } 69 70 71 } 72 while(ls.store != 0){ 73 arr.push(ls.pop()); 74 } 75 return arr; 76 console.log(arr); 77 } 78 79 //------------------------Testing--------------------------------------- 80 function main(){ 81 //输入时做提示,以空格间隔每个操作符和操作数 82 //var normalC = ' 1 - ( 2 + 3 ) * 4 * 2 + 10 / 5 '; 83 var normalC = '2 + 3 * 4 * ( 3 - 2 )'; 84 var stack = new Stack(); 85 var char = normalChar(normalC); 86 var p = 0,s = 0; 87 var reg = /\d/; 88 for(var i=0; i<char.length; i++){ 89 if(reg.test(char[i])){ 90 stack.push(char[i]); 91 }else{ 92 switch(char[i]){ 93 case '-': 94 p = stack.pop(); 95 s = stack.pop(); 96 stack.push(Number(s)-Number(p)); 97 break; 98 case '+': 99 p = stack.pop(); 100 s = stack.pop(); 101 stack.push(Number(s)+Number(p)); 102 break; 103 case '*': 104 p = stack.pop(); 105 s = stack.pop(); 106 stack.push(Number(s)*Number(p)); 107 break; 108 case '/': 109 p = stack.pop(); 110 s = stack.pop(); 111 if(p != 0){ 112 stack.push(Number(s)/Number(p)); 113 }else{ 114 console.log("除数不能为0"); 115 break; 116 } 117 } 118 } 119 } 120 console.log(stack.store); 121 } 122 main(); 123 124 125 126 127 128 129