1. g一个字符串s是一个有效的四则运算表达式,请计算该表达式的值
    • 1+2,得到3
    • 2*(2+3),得到10
    • (15%(5-3)+6)*(2+3) ,得到35

    字符串s至少包含一个运算符
    字符串a中的操作数均为数字字面量,但可能包含小数
    完成下面代码

    1. /*
    2. * 得到四则运算的结果
    3. * @params {String} s四则运算表达式
    4. * @return {Boollean}
    5. */
    6. function compute(s){
    7. // code here
    8. }

    image.png
    image.png

    demo

    1. // 声明一个栈,用于存放数据
    2. class Stack {
    3. // 存放栈数据的数组
    4. _datas = [];
    5. // 放入栈一条数据
    6. push = function (data) {
    7. this._datas.push(data);
    8. };
    9. // 栈中弹出一个数据
    10. pop = function () {
    11. return this._datas.pop();
    12. };
    13. // 去除栈顶的数据
    14. getTop = function () {
    15. return this._datas[this._datas.length - 1];
    16. };
    17. }
    18. // 声明四则运算的表达方式 (+-*/%)
    19. const operators = {
    20. "+": {
    21. level: 1,
    22. compute(num1, num2) {
    23. return num1 + num2;
    24. },
    25. },
    26. "-": {
    27. level: 1,
    28. compute(num1, num2) {
    29. return num1 - num2;
    30. },
    31. },
    32. "*": {
    33. level: 2,
    34. compute(num1, num2) {
    35. return num1 * num2;
    36. },
    37. },
    38. "/": {
    39. level: 2,
    40. compute(num1, num2) {
    41. return num1 / num2;
    42. },
    43. },
    44. "%": {
    45. level: 2,
    46. compute(num1, num2) {
    47. return num1 % num2;
    48. },
    49. },
    50. };
    51. /**
    52. * 声明一个扫描器
    53. * @param {*} s 字符串
    54. */
    55. function Scanner(s) {
    56. // 剔除表达式的中的空格
    57. this.s = s.replace(/\s/g, "");
    58. // 判断下一个卡开头字符串是不是数字
    59. this.numberExp = /^\d+(\.\d+)?/;
    60. // 判断下一个字符是不是运算符
    61. this.opExp = /^[\(\)\+\-\*\/\%]/;
    62. }
    63. //获取字符串的下一个字符
    64. Scanner.prototype.next = function () {
    65. // 如果字符串为空直接返回
    66. if (this.s.length === 0) {
    67. return null;
    68. }
    69. // 数字表达的结果
    70. const match = this.s.match(this.numberExp);
    71. // 保存返回结果
    72. let result;
    73. if (match) {
    74. result = {
    75. type: "number",
    76. value: +match[0],
    77. };
    78. // 匹配过的字符删除
    79. this.s = this.s.substr(match[0].length);
    80. } else {
    81. result = {
    82. type: "operator",
    83. value: this.s[0],
    84. };
    85. // 匹配过的字符串删除
    86. this.s = this.s.substr(1);
    87. }
    88. return result;
    89. };
    90. // 声明一个计算函数
    91. function compute(s) {
    92. // 声明一个栈保存数字
    93. const numberStack = new Stack();
    94. // 声明一个字符栈保存操作符
    95. const opStack = new Stack();
    96. // 声明一个辅助计算函数
    97. function _compute() {
    98. // 获取符号栈栈顶操作符
    99. const topOp = opStack.getTop();
    100. if (!topOp) {
    101. return false;
    102. } else if (topOp === "(") {
    103. opStack.pop();
    104. return false;
    105. } else {
    106. opStack.pop();
    107. const num1 = numberStack.pop();
    108. const num2 = numberStack.pop();
    109. const result = operators[topOp].compute(num2, num1);
    110. numberStack.push(result);
    111. return true;
    112. }
    113. }
    114. // 声明一个处理操作符的函数
    115. function _handeNextOpertator(op) {
    116. let topOp = opStack.getTop(); // 得到目前栈顶的符号
    117. if (op === ")") {
    118. while (_compute()) {}
    119. } else if (
    120. !topOp ||
    121. op === "(" ||
    122. topOp === "(" ||
    123. operators[op].level > operators[topOp].level
    124. ) {
    125. // 如果栈顶是空,当前符号是(,或者栈顶是(),或者当前符号的优先级高,直接入栈
    126. opStack.push(op);
    127. } else {
    128. // 如果当前的符号优先级<=栈顶符号,运算,递归运算
    129. _compute();
    130. _handeNextOpertator(op);
    131. }
    132. }
    133. // 扫描器
    134. const scanner = new Scanner(s);
    135. let next;
    136. while ((next = scanner.next())) {
    137. if (next.type === "number") {
    138. numberStack.push(next.value);
    139. } else {
    140. _handeNextOpertator(next.value);
    141. }
    142. }
    143. // 符号栈清空
    144. while (_compute());
    145. // 返回计算结果
    146. return numberStack.getTop();
    147. }
    148. const result = compute("2.5 * ( 4 + 6 ) - 2*3%5");
    149. console.log("result", result);