93 lines
2.3 KiB
JavaScript
93 lines
2.3 KiB
JavaScript
function evalRpn(input) {
|
|
var outputStack = [];
|
|
var rpnQueue = toRPolish(input);
|
|
while (rpnQueue.length > 0) {
|
|
var cur = rpnQueue.shift();
|
|
|
|
if (!isOperatorR(cur)) {
|
|
outputStack.push(cur);
|
|
} else {
|
|
if (outputStack.length < 2) {
|
|
throw "unvalid stack length";
|
|
}
|
|
var sec = outputStack.pop();
|
|
var fir = outputStack.pop();
|
|
|
|
outputStack.push(getResult(fir, sec, cur));
|
|
}
|
|
}
|
|
|
|
if (outputStack.length != 1) {
|
|
throw "unvalid expression";
|
|
} else {
|
|
return outputStack[0];
|
|
}
|
|
}
|
|
|
|
function getResult(fir, sec, cur) {
|
|
var s = fir + cur + sec;
|
|
var r = eval(s);
|
|
if (r < 0) {
|
|
r = r * -1;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
function isOperatorR(value) {
|
|
var operatorString = "+-*/";
|
|
return operatorString.indexOf(value) > -1
|
|
}
|
|
|
|
function isOperatorF(value) {
|
|
var operatorString = "(){}[]";
|
|
return operatorString.indexOf(value) > -1
|
|
}
|
|
|
|
function toRPolish(input) {
|
|
var regex = /(\+|\-|\*|\/)+/;
|
|
var array = input.replaceAll('\\(', '').replaceAll('\\)', '').replaceAll('\\{', '').replaceAll('\\}', '').replaceAll('\\[', '').replaceAll('\\]', '').split(regex);
|
|
var RPolish = ""
|
|
var isI = false;
|
|
num = 0;
|
|
var SymbolArray = new Array(100);
|
|
var SymbolNum = -1;
|
|
for (j = 0; j < input.length; j++) {
|
|
if (input.charAt(j).match(/\d/)) {
|
|
if (isI == false) {
|
|
if (RPolish.length > 0) {
|
|
RPolish += ','
|
|
}
|
|
RPolish += array[num];
|
|
num++;
|
|
isI = true;
|
|
}
|
|
}
|
|
else {
|
|
var c = input.charAt(j);
|
|
if (isOperatorR(c)) {
|
|
num++;
|
|
}
|
|
if (!isOperatorF(c)) {
|
|
SymbolNum++;
|
|
SymbolArray[SymbolNum] = input.charAt(j);
|
|
}
|
|
isI = false;
|
|
}
|
|
}
|
|
while (SymbolNum >= 0) {
|
|
RPolish += ',';
|
|
RPolish += SymbolArray[SymbolNum];
|
|
SymbolNum--;
|
|
}
|
|
regex = /,/;
|
|
var RPolishArray = RPolish.split(regex);
|
|
return RPolishArray;
|
|
}
|
|
|
|
function compare(a, b) {
|
|
if ((a.match(/\*/) || a.match(/\//)) && (b.match(/\+/) || b.match(/\-/))) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|