双 '+' 符号与 JS 中的 !NaN 混淆

问题描述

为波兰表示法工作,我正在添加一种方法来区分我得到的字符串是否为数字,使用 isNaN 函数。这工作正常,直到您将 ++ 添加到字符串中。

function cuttingString(list) {
    let adjustArr = list.split(' ')
    let topper = []
    for (let i = 0; i < adjustArr.length; i++) {
        if (!isNaN(adjustArr[i])) {
            topper.push(adjustArr[i])
            console.log(topper)
        } else {
            let j = topper.pop()
            let k = topper.pop()

            if (adjustArr[i] === '+') {
                topper.push(parseInt(j) + parseInt(k))
            }
        }
    }
}

console.log(cuttingString('* 1 2 30 +'))

按预期与 '* 1 2 30 +' 一起工作,它输出 [1,2,30] 但是,当我开始在运算符周围移动时,是当我在数组 [NaN,1,30] 的开头得到 NaN 时,这非常令人沮丧.关于如何解决此问题或其他解决方法的任何想法?

解决方法

您的代码似乎实现了反向波兰表示法,因此如果您没有在任何二元运算符之前提供参数,您就不能期望它能够正常工作。因此,您不能在表达式中随意移动 +。二元运算符只有在堆栈上至少有两个可用数字时才能出现。如果不是,对 pop 的调用将返回 undefined,而 parseInt(undefined)NaN。虽然你还没有实现乘法,但是 * 发生在堆栈仍然为空的时候是有问题的。

让您的函数返回结果是有意义的,因为您的 console.log 目前只会输出 undefined,因此您实际上并没有看到结果计算。

如果确实,您的想法是为反向波兰表示法实现一个求值器,那么以下是我将适应您的代码的内容:

function cuttingString(list) {
    // Allow multiple spaces,also at start/end:
    let adjustArr = list.match(/\S+/g); 
    let topper = [];
    // Use for..of loop
    for (let token of adjustArr) {
        if (!isNaN(token)) {
            // Why not convert to number here...
            //   and allow decimals. Use unary plus
            topper.push(+token);
        } else if (topper.length < 2) {
            // Show error message when not enough arguments
            throw "not enough arguments for " + token;
        } else {
            let j = topper.pop();
            let k = topper.pop();
            if (token === '+') {
                topper.push(j + k);
            }
        }
    }
    // Verify that the evaluation is complete
    if (topper.length !== 1) {
        throw "Evaluation did not yield one value but " + topper.length;
    }
    // Return the value 
    return topper.pop();
}

console.log(cuttingString('1 2 30 + +')); // 33
console.log(cuttingString('1 2 + 30 +')); // 33

此代码中的两个示例是您可以将 + 运算符移动到的唯一位置。例如,以下情况均无效:

console.log(cuttingString('1 2 + + 30'));
console.log(cuttingString('1 + 2 30 +'));

在任何一种情况下,都会出现堆栈没有足够的二元运算符参数的情况。上面的代码将为此提供特定的错误消息。