为什么javascript会跳过数学字符串的最后一部分?

时间:2014-01-21 18:25:49

标签: javascript loops math for-loop

用户输入数学问题,问题就解决了。我的代码适用于所有1个部分的问题,例如“1 + 1”和“4 * 5”。但之后它会跳过问题的最后部分。例如“1 + 1 + 1”输出2和“1 + 1 + 1 + 1”输出3和“4 * 5-6”输出20.我在这里做错了什么?我觉得这很简单,但我尝试了一些事情。

相关代码:

function scan(i) {
    "use strict";
    var num,
    schar = "",
    strnum = "",
    scanarray = [];
    for (i; i <= input.length; i++ ) {
        schar = input.charAt(i);
        if (isoperator(schar)) {
        break;
        }
        strnum = strnum + schar;
    } 
    if (strnum !== "") { num = Number(strnum); }
    scanarray[0] = schar;
    scanarray[1] = i;
    scanarray[2] = num;
    return scanarray;
}

for (i; i <= input.length; i) {
    scanarray = scan(i + 1);
    schar = scanarray[0];
    i = scanarray[1];
    num = scanarray[2];
    if (schar1 !== "") {
        switch(schar1)
        {
            case "+":
                answer = num1 + num;
                break;
            case "-":
                answer = num1 - num;
                break;
            case "*":
                answer = num1 * num;
                break;
            case "/":
            case "÷":
                answer = num1 / num;
                break;
        }
        schar1 = "";
    } else {
        switch(schar)
        {
            case "+":
                answer = answer + num;
                break;
            case "-":
                answer = answer - num;
                break;
            case "*":
                answer = answer * num;
                break;
            case "/":
            case "÷":
                answer = answer / num;
                break;
        }
    }
}

我尝试在扫描功能中更改for循环直到“i&lt; = input.length + 1”并且计算功能中的for循环相同,我尝试更改两者,但没有一个工作。任何帮助是极大的赞赏!

2 个答案:

答案 0 :(得分:0)

这是非常天真地重新实现您的代码,至少应该让您朝着更加惯用的Javascript方式实现目标,而不是相对不可读的C-像逐步通过输入的每个字符的方法。我认为可以说各种正则表达式也难以阅读,但它们在简洁中弥补了这一点,这反过来又有助于可维护性,我认为你的代码不能按预期的方式工作的原因是可维护性问题。

console.log(" 44 * 5 - 6 / 2 + 4 =", performMath(" 44 * 5 - 6 / 2 + 4")); 
console.log("4*5-2 =", performMath("4*5-2")); 


function performMath(input) {
  var output, operands, operators;

  input = input.replace(/\s+/g, '');

  if (input.match(/\d+([\*-]\d+)*/g)) {
    operands = input.split(/[-\*\/\+]/);
    operators = input.split(/\d+/).filter(function(i) {
      return i
    });

    for (var i = 0, n = operators.length; i < n; i++) {
      output = output || operands[0];
      eval("output=output" + operators[i] + operands[i + 1]);
    }
  }

  return output;
}

答案 1 :(得分:0)

这是一种避免使用eval并正确遵循操作顺序的方法。诀窍是先处理乘法和除法(从左到右),然后处理加法和减法(从左到右)。如果你想要更加漂亮,那么你可能想要研究诸如Shunting Yard Algorithm之类的算法。

console.log(" 44 * 5 - 6 / 2 + 4 =", performMath(" 44 * 5 - 6 / 2 + 4")); 
console.log("4*5-2 =", performMath("4*5-2")); 

function performMath(input) {
  input = input.replace(/\s+/g,'');
  input = input.replace(/\d+[*/]\d+/g,performMult);
  while ( /[+-]/.test(input) ) {
    input = input.replace(/^(\d+)([+-])(\d+)/,oneOper);
  }
  return input;
}
function performMult(input) {
  while ( /[*/]/.test(input) ) {
    input = input.replace(/^(\d+)([*/])(\d+)/,oneOper);
  }
  return input;
}
function oneOper(m,p1,p2,p3) {
  switch (p2) {
  case '+': return +p1 + +p3;
  case '-': return +p1 - +p3;
  case '*': return +p1 * +p3;
  case '/': return +p1 / +p3;
  }
}