Написал вычисления по обратной польской нотации. Но если умножение идет за делением результат не сходится с калькулятором
Подозреваю что у них разные приоритеты друг над другом. И что с этим делать?
// Берем выражение 20*(47-60/-3+9)+978/6+(32-21*3) Получаем 1652
// Берем 20*(47-60/-3+9)+978/6*(32-21*3)
// По калькулятору нужно -3533, но дает -42873
//let s = '20*(47-60/-3+9)+978/6+(32-21*3)';
let s = '20*(41-60/-3)+978/6*(32-21*3)'
// разделяем на числа, скобки и знаки
let ss = s.split('');
let st1 = [];
for (var i = 0; i < ss.length - 1; i++) {
if ((!isNaN(ss[i]) && isNaN(ss[i + 1])) || (isNaN(ss[i]) && !isNaN(ss[i + 1]))) {
ss.splice(i + 1, 0, ' ');
i++;
}
}
sss = ss.join('').split(' ');
for (var i = 0; i < sss.length; i++) {
if (isNaN(sss[i])) {
t = sss[i].split('');
sss[i] = t;
}
}
sss = sss.flat();
// отрицательные
if (sss[0] == '-') {
let changeFirstABS = -sss[1];
sss[1] = changeFirstABS;
sss.splice(0, 1);
}
for (var i = 0; i < sss.length; i++) {
if (!isNaN(sss[i]) && sss[i - 1] == '-' && isNaN(sss[i - 2])) {
t = -sss[i];
sss[i] = t;
sss.splice(i - 1, 1);
}
}
// отрицательные
for (var i = 0; i < sss.length; i++) {
if (!isNaN(sss[i])) {
sss[i] = parseInt(sss[i])
}
}
console.log(sss);
// из строки получили массив положительных и отрицательных чисел, скобок и знаков
// теперь переводим его из инфиксной записи в постфиксную
ops = {
'+': 1,
'-': 1,
'/': 2,
'*': 2
};
s = sss;
stack = [];
out = [];
for (var i = 0; i < s.length; i++) {
if (!isNaN(s[i])) {
out.push(s[i]);
}
if (isNaN(s[i])) {
a = stack[stack.length - 1];
if (stack.length == 0) {
stack.push(s[i])
} else {
if (s[i] == '(' || a == '(') {
stack.push(s[i])
}
if (ops[a] >= ops[s[i]]) {
out.push(a);
stack.pop();
openBracket = stack.lastIndexOf('(');
n = stack.splice(openBracket + 1).reverse().join('');
out.push(n);
out = out.flat();
stack.push(s[i]);
}
if (ops[a] < ops[s[i]]) {
stack.push(s[i]);
}
if (s[i] == ')') {
while (stack[stack.length - 1] != '(') {
out.push(stack[stack.length - 1]);
stack.pop();
}
stack.pop();
}
}
}
}
if (stack.length != 0) {
while (stack.length > 0) {
out.push(stack[stack.length - 1]);
stack.pop();
}
}
for (var i = 0; i < out.length; i++) {
if (out[i] == '') {
out.splice(i, 1);
i--;
}
}
console.log('out is', out);
// перевели в постфиксную запись
// обратная польская нотация и стек
let stack2 = [];
for (var i = 0; i < out.length; i++) {
if (!isNaN(out[i])) {
stack2.push(out[i])
} else {
if (out[i] == '*') {
var res = stack2[stack2.length - 2] * stack2[stack2.length - 1];
stack2.splice(stack2.length - 2);
stack2.push(res);
}
if (out[i] == '+') {
var res = stack2[stack2.length - 2] + stack2[stack2.length - 1];
stack2.splice(stack2.length - 2);
stack2.push(res);
}
if (out[i] == '-') {
var res = stack2[stack2.length - 2] - stack2[stack2.length - 1];
stack2.splice(stack2.length - 2);
stack2.push(res);
}
if (out[i] == '/') {
var res = stack2[stack2.length - 2] / stack2[stack2.length - 1];
stack2.splice(stack2.length - 2);
stack2.push(res);
}
}
}
console.log(res);
// подсчитали