遍历堆栈以获得总和

时间:2019-09-25 11:20:09

标签: javascript arrays stack

我目前正在使用Javascript开发计算器。单击的按钮存储在堆栈中。 例如,我们单击“ 54”,“ +”,“ 23”。那将是77,对吧? 因此,现在我的堆栈显示此 [“ 54”,“ +”,“ 23”,“ =”,“”] 我希望堆栈的结果如下: [“ 54”,“ +”,“ 23”,“ =”,“”,“ 77”] 如果您也知道如何在堆栈中删除空字符串,那真是太棒了。

const value = event.target.value;

            if(isNaN(parseInt(value, 10)))
            {
                stack.push(value)
                stack.push('')

            } else if(stack.length > 0)
            {
                stack[stack.length - 1] += '' + value; 
            }
            if (prevop == '=') {
                document.getElementById("textfield").value = "";
            }

            prevop = value;

我正在尝试实现她下面的逻辑,以获得我想要的结果。

            var sum = 0;
            var stackLength = stack.length;
            for(var i = 0; i < stackLength; i++)
            {
                sum = sum + stack.pop();
                stack.push(sum);
            }

2 个答案:

答案 0 :(得分:0)

您可以尝试使用eval。但是请记住,eval对于代码注入很危险:

function calc(stack){
    const i = stack.findIndex(x => x === '=');
    const expression = stack.slice(0, i).join('');

    stack[stack.length - 1] = '' + eval(expression);

    return stack; 
}

UPD:不带eval的解决方案。请注意,此解决方案未考虑操作员的优先级。

function calc(stack) {
    let res = +stack[0];

    for (let i = 1; i < stack.length; i += 2) {
        const operator = stack[i];
        const rightNumber = stack[i + 1];

        switch (operator) {
            case '+': res += +rightNumber; break;
            case '-': res -= +rightNumber; break;
            case '*': res *= +rightNumber; break;
            case '/': res /= +rightNumber; break;
            case '=': stack[stack.length - 1] = '' + res; return stack;
        }
    }
}

答案 1 :(得分:0)

您可以使用第二个堆栈来保存中间结果,然后将该堆栈清空到输入数组的顶部。

示例

function evaluate(arr) {
    const array = [...arr];
    const stack = [];
    const pop = () => stack.pop();
    const shift = () => array.shift();
    const operators = {
        "+"() { return Number(pop()) + Number(shift()) },
        "-"() { return pop() - shift() },
        "*"() { return pop() * shift() },
        "/"() { return pop() / shift() },
        "="() { return pop()},
    };   
    while(array.length) {
        const val = shift();
        stack.push(operators[val] ? operators[val]() : val);
    }
    arr.push(pop());
    return arr;
}

// Examples
console.log(evaluate(["10", "+", "20", "="]).join(" "));
console.log(evaluate(["10", "*", "20", "="]).join(" "));
console.log(evaluate(["10", "-", "20", "="]).join(" "));
console.log(evaluate(["10", "/", "20", "="]).join(" "));
console.log(evaluate([10, "+", 20, "+", 30,"="]).join(" "));

添加优先级和嵌套方括号。

请注意,新版本假定该数组以"="结尾

function evaluate(array) {
  const operators = {  // operators must be in order of precedence
    "**"(){ return left() ** right() },
    "*"() { return left() * right() },
    "/"() { return left() / right() },
    "%"() { return left() % right() },
    "+"() { return left() + Number(right()) },
    "-"() { return left() - right() },
  }; 
  const order = Object.keys(operators);  
  const a = [...array];
  const index = (val, idx = i) => i = a.indexOf(val, idx);
  const left = () => a[i - 1], right = () => a[i + 1];
  const OK = () => a.length > 2;
  const brackets = () => {
    var i = -1;
    while ((i = index("(", i + 1)) > -1) {
      a.splice(i, 1);
      let depth = 1;
      const sub = [];
      while (depth) {
        const val = a.splice(i, 1)[0];
        val === "(" && depth++ || val === ")" && depth--;
        depth && sub.push(val);
      }
      a.splice(i, 0, evaluate(sub).pop());
    }
  }
  brackets();
  var i;
  while (OK() && order.length) {
    const op = order.shift(), func = operators[op];
    i = 0;
    while (OK() && index(op) > -1) { a.splice(i - 1, 3, func()) }
  }
  array.push(a[0])
  return array;
}

console.log(evaluate([10, "+", "(", 20, "-", 30, ")", "+", 20, "+", 20, "*", 30, "/", 30, "="]).join(""))