Цикл стека, чтобы получить сумму - PullRequest
0 голосов
/ 25 сентября 2019

В настоящее время я работаю над калькулятором в Javascript.Кнопки, на которые нажимаются, хранятся внутри Stack .Например, мы нажимаем «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 голосов
/ 25 сентября 2019

Вы можете использовать второй стек для хранения промежуточных результатов, а затем очистить этот стек до верха входного массива.

Пример

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(""))
0 голосов
/ 25 сентября 2019

Вы можете попробовать использовать 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;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...