Reputation: 400
Working a evaluator for Polish Notation and I was adding a way to distinguish if the string I got was a number or not using the isNaN function. This works fine, until you add + + to the string.
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 +'))
works as expected with '* 1 2 30 +'
it outputs [1,2,30]
However, when I start moving around the operators, is when I get a NaN in the beginning of my arrays [NaN, 1,2,30]
which is incredibly frustrating. Any ideas on how to fix this problem or other work arounds?
Upvotes: 0
Views: 153
Reputation: 350310
Your code seems to implement reverse Polish notation, and so you cannot expect it to work correctly if you don't provide arguments before any of the binary operators. So you cannot randomly move the +
around in the expression. A binary operator can only occur if there are at least two numbers available on the stack. If not, the call to pop
will return undefined
and parseInt(undefined)
is NaN
. Although you did not implement multiplication yet, it is problematic that the *
occurs at a time when the stack is still empty.
It would make sense to have your function return the result, as your console.log
will currently only output undefined
and so you don't actually see the result of the calculation.
If indeed, your idea was to implement an evaluator for reverse Polish notation, then here is what I would adapt to your code:
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
The two examples in this code are the only places where you can move the +
operator to. For instance, neither of the following is valid:
console.log(cuttingString('1 2 + + 30'));
console.log(cuttingString('1 + 2 30 +'));
In either case, there arises a situation where the stack does not have enough arguments for a binary operator. The code above will provide a specific error message for that.
Upvotes: 1