【问题标题】:Why is for loop skipping part of string?为什么for循环跳过字符串的一部分?
【发布时间】:2021-04-08 00:15:18
【问题描述】:

我正在创建一个遵循操作顺序的计算器应用程序。我的问题是 else if 在第 10 行检查括号。我想要它检查一个开放的括号,递归地通过我的 Calculator 方法运行里面的内容,将它推入我解析的字符串数组以再次计算,从我的字符串中删除括号,然后再次从 0 开始 i 移动我的字符串前面的 for 循环。由于某种原因,它会跳到第二个括号并运行两次。这是我的代码:

Calculator("(3*2)/(2+1)+4");
//Should get 3
function parseCalculationString(expression){
    let parsedString = [];
    for(i = 0; i<expression.length; i++){
        if(expression[i]!=" "){
            if (expression[i]>='0' && expression[i]<='9'){
                parsedString.push(parseFloat(expression[i]));
            }
            else if(expression[i] == '('){
                //let parentheses = Calculator(expression.split('(').pop().split(')')[0]);
                let subExpression = expression.split('(').pop().split(')')[0];
                console.log(subExpression)
                parsedString.push(Calculator(subExpression))
                console.log(parsedString)
                expression = expression.substring(expression.indexOf(')')+1)
                console.log(expression)
                i=0;
                
            }
            else{
                parsedString.push(expression[i]);
            }    
        }
        
    }
    return parsedString;
}
function Calculator(str) {  
  // code goes here
  let parsedExpression = parseCalculationString(str);
  const operations = ['*', '/', '+', '-']
  for (i = 0; i < operations.length; i++){
    for(j = 0; j < parsedExpression.length; j++){
        if(operations[i] == parsedExpression[j]){
            if(operations[i] == '*'){
                Array.prototype.splice.apply(parsedExpression, [j-1, 3].concat(parsedExpression[j-1]*parsedExpression[j+1]));
            }
            else if(operations[i] == '/'){
                Array.prototype.splice.apply(parsedExpression, [j-1, 3].concat(parsedExpression[j-1]/parsedExpression[j+1]));
            }
            else if(operations[i] == '+'){
                Array.prototype.splice.apply(parsedExpression, [j-1, 3].concat(parsedExpression[j-1]+parsedExpression[j+1]));
            }
            else if(operations[i] == '-'){
                Array.prototype.splice.apply(parsedExpression, [j-1, 3].concat(parsedExpression[j-1]-parsedExpression[j+1]));
            }
        } 
        
      }
  }
  
  str = parsedExpression[0];
  
  return str; 

}

我的输出:

2+1 
(1) [3]
/(2+1)+4 
2+1 
+4

我的预期输出:

3*2
[6]
/(2+1)+4
2+1
[6,/,3]
+4

【问题讨论】:

  • 大概这部分:expression.split('(').pop()。这会将您的测试表达式分成 3 部分并抓取最后一部分。你可能想要expression.split('(')[1]
  • 也可能发布您的算法。你说递归,但我看到循环引用。如果没有正确方法的指导算法,很难调试复杂的代码。
  • 循环引用是当你调用一个函数,你调用的函数调用调用者。你在你的方法中这样做。 parseCalculationString 调用 Calculator,反之亦然。这本身不是问题。这显然是你的方法。
  • 如果是“递归”,那么Calculator() 会调用自己。在您的问题中,情况似乎并非如此。不管。只要它有效。但可能,“指导算法”确实使用递归,在这里你有循环引用。 ....所以这就是我建议您在问题中包含算法的部分原因。另一个原因将有助于社区调试其他问题。
  • 无论如何,赞成。这是您的一次崇高的编码尝试。

标签: javascript arrays for-loop syntax


【解决方案1】:
<script>
    console.log("===>", Calculator("(3*2)/(2+1)+4"));
    //Should get 3
    function parseCalculationString(expression) {
        let parsedString = [];
        for (i = 0; i < expression.length; i++) {
            if (expression[i] != " ") {
                if (expression[i] >= '0' && expression[i] <= '9') {
                    parsedString.push(parseFloat(expression[i]));
                }
                else if (expression[i] == '(') {
                    let subExpression = expression.split('(')[1].split(')')[0];
                    console.log(subExpression)
                    parsedString.push(Calculator(subExpression))
                    console.log(parsedString)
                    expression = expression.substring(expression.indexOf(')') + 1)
                    console.log(expression)
                    i = 0;
                }
                else {
                    parsedString.push(expression[i]);
                }
            }

        }
        return parsedString;
    }
    function Calculator(str) {
        // code goes here
        let parsedExpression = parseCalculationString(str);
        const operations = ['*', '/', '+', '-']
        for (i = 0; i < operations.length; i++) {
            for (j = 0; j < parsedExpression.length; j++) {
                if (operations[i] == parsedExpression[j]) {
                    if (operations[i] == '*') {
                        Array.prototype.splice.apply(parsedExpression, [j - 1, 3].concat(parsedExpression[j - 1] * parsedExpression[j + 1]));
                    }
                    else if (operations[i] == '/') {
                        Array.prototype.splice.apply(parsedExpression, [j - 1, 3].concat(parsedExpression[j - 1] / parsedExpression[j + 1]));
                    }
                    else if (operations[i] == '+') {
                        Array.prototype.splice.apply(parsedExpression, [j - 1, 3].concat(parsedExpression[j - 1] + parsedExpression[j + 1]));
                    }
                    else if (operations[i] == '-') {
                        Array.prototype.splice.apply(parsedExpression, [j - 1, 3].concat(parsedExpression[j - 1] - parsedExpression[j + 1]));
                    }
                }

            }
        }
        str = parsedExpression[0];
        return str;
    }
</script>

//刚刚更新了下面这行

let subExpression = expression.split('(').pop().split(')')[0];

let subExpression = expression.split('(')[1].split(')')[0];

【讨论】:

  • (3*2*3)/(2+1)+4") !== 6
  • 解决表达式的正确方法是使用中缀到后缀的转换,然后使用堆栈对其进行评估。对于这个表达式 (3*2*3)/(2+1)+4,问题出在 Calculator() 方法中,它只需要 2 个操作数和 1 个运算符。否则使用 ( )。
  • 还有一件事,如果我们使用嵌套括号,这段代码将不起作用。
  • 很高兴您注意到嵌套括号中的 @AshishTiwari。代码需要更多的测试用例才能完全调试。我个人对起源“算法”很好奇。
  • 我认为我已经解决了,请在我的 github github.com/daniil-loban/no_polish_notation_calculator/blob/main/… 中查看它,如果你喜欢它,请给我一个星 :) 或者写我关于问题
猜你喜欢
  • 1970-01-01
  • 2013-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 2013-01-11
相关资源
最近更新 更多