【javascript】无括号表达式求值

无括号表达式求值


  • 博主前面发过c语言写的,这次用javascript写还是花了不少时间,还有一些新的体会。

代码收获


  • javascript主要一开始给你的是字符串,如果使用pharseint中间有除法除出小数就不好计算了。
  • 博主这次搞错逻辑了,一开始以为优先级相同直接入栈,优先级相同也需要弹栈进行运算,这样最后就不会有变号问题,只有优先级高的情况才能入栈,结果就能对了。
  • 优先级用二重数组有点麻烦,应该使用字典那种会方便处理。
  • 确定好步骤,如果边想边写,改动太多,熟练使用while,大致做个流程图,或者先写个伪代码,把全局步骤写一遍,写出来会很方便。

//入栈 push
//出栈 pop

var nNumstack = []; //数字栈
var oOperastack = []; //操作符栈

//优先级
var priority = [
    ['+', 0],
    ['-', 0],
    ['*', 1],
    ['/', 1]
];

var stext = '5+5/3-9-2'; //测试语句
console.log(stext);
var iindex = 0;
//入数字栈
function pushnumstack(iindex, stext, nNumstack) {
    itext = stext.charAt(iindex);
    itext = parseFloat(itext);
    if (isNaN(itext) == true) {
        throw ("字符不是数字:" + itext);
    } else {
        nNumstack.push(itext);
    }
}
//入操作栈
function pushopstack(iindex, stext, oOperastack, priority) {
    itext = stext.charAt(iindex);
    var sig = 0;
    for (var i = 0; i < priority.length; i++) {
        if (itext == priority[i][0]) {
            sig++;

        }
    }
    if (sig > 0) {
        oOperastack.push(itext);
    } else {
        throw ("操作符未取到s")
    }
}


if (nNumstack.length == 0) { //先入第一个数字
    pushnumstack(iindex, stext, nNumstack);
    iindex++;
} else {
    throw ("请清空数组");
}
//入操作符
if (oOperastack.length == 0) {
    pushopstack(iindex, stext, oOperastack, priority);
    iindex++;
} else {
    throw ("请清空数组");
}

//入下一个操作数
pushnumstack(iindex, stext, nNumstack);
iindex++;

//判断下一个操作符优先级
function compareop(stext, iindex, oOperastack, priority) {
    var nextop = stext.charAt(iindex);
    var stacklastop = oOperastack[oOperastack.length - 1];
    var nextoppy;
    var stackoppy;
    if (stacklastop == undefined) {
        return 1;
    }
    for (var i = 0; i < priority.length; i++) {
        if (priority[i][0] == nextop) {
            nextoppy = priority[i][1];
        }
        if (priority[i][0] == stacklastop) {
            stackoppy = priority[i][1];
        }
    }
    if (nextoppy > stackoppy) {
        return 1; //下一个优先级大于栈内
    } else {
        if (nextoppy == stackoppy) {
            return 0; //等于栈内优先级
        } else {
            return -1; //小于栈内
        }
    }
}

//进行判断
sigpy = compareop(stext, iindex, oOperastack, priority);

//如果1,,压栈,如果-1,0,把数字栈2个数字和操作栈1个操作符弹出进行计算,值重新入数字栈,操作符入栈
function judgeflow(stext, iindex, oOperastack, nNumstack, priority, sigpy) {
    var res;
    if (sigpy > 0) {
        pushopstack(iindex, stext, oOperastack, priority);
        iindex++;
        pushnumstack(iindex, stext, nNumstack);
        iindex++;
        return iindex;
    } else {
        num1 = nNumstack.pop();
        num2 = nNumstack.pop();
        ops = oOperastack.pop();
        num1 = parseFloat(num1);
        num2 = parseFloat(num2);
        switch (ops) {
            case "+":
                {
                    res = num1 + num2;
                    break
                };
            case "-":
                {
                    res = num2 - num1;
                    break;
                }
            case "*":
                {
                    res = num2 * num1;
                    break
                };
            case "/":
                {
                    res = num2 / num1;
                    break
                };
            default:
                throw ("操作符错误", ops);
        }


        nNumstack.push(res);

        return iindex;
    }

}

//进行判断

iindex = judgeflow(stext, iindex, oOperastack, nNumstack, priority, sigpy);
//判断iindex是否等于length,不等说明还要继续
while (iindex < stext.length) {
    sigpy = compareop(stext, iindex, oOperastack, priority);
    iindex = judgeflow(stext, iindex, oOperastack, nNumstack, priority, sigpy);
}
//进行出栈计算 最后会剩一个结果
while (oOperastack.length > 0) {
    var res;
    num1 = nNumstack.pop();
    num2 = nNumstack.pop();
    ops = oOperastack.pop();
    num1 = parseFloat(num1);
    num2 = parseFloat(num2);
    ops2 = oOperastack[oOperastack.length - 1];

    switch (ops) {
        case "+":
            {
                res = num1 + num2;

                break
            };
        case "-":
            {
                res = num2 - num1;
                break;
            }
        case "*":
            {
                res = num2 * num1;
                break
            };
        case "/":
            {
                res = num2 / num1;
                break
            };
        default:
            throw ("操作符错误");
    }

    nNumstack.push(res);
}
console.log(nNumstack);

5+5/3*6+5*7
[ 50 ]
5+5/3-9-2
[ -4.333333333333333 ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值