目录
如果想看具体算法描述请访问:《计算机软件技术实习 项目一 简单计算器的实现(实验准备)1-(1)》https://blog.csdn.net/qq_53500812/article/details/121534855?utm_source=app&app_version=4.18.0&code=app_1562916241&uLinkId=usr1mkqgl919blen
一、String数组转为算数表达式
有括号相关bug,解决方案请访问:bug解决
/**
* 数字的合成
*/
for (var i in arr) {
// 如果当前遇到的是数字/小数点/正负号
if (false === isNaN(arr[i]) || arr[i] === this.data.idPoint || arr[i] === this.data.idNegative) {
num += arr[i];
}
//如果当前遇到的是括号开和括号毕
else if (arr[i] === this.data.idkhk) {
optarr.push(arr[i]);
}
// 否则,是运算符
else {
// 存入合成操作数数组
optarr.push(num);
optarr.push(arr[i]);
// 清空当前合成的操作数
num = "";
}
}
// 最后一个数字不会遇到运算符,将它也存入数组中
if (num !== "") {
optarr.push(num);
}
二、中缀表达式转后缀表达式
/**
* 中缀转后缀
*/
for (var i in optarr) {
//如果遇到的操作符是左括号"(”,就直接将该操作符输出到堆栈当中
if (optarr[i] === this.data.idkhk) {
InfixEXp.push(optarr[i]);
console.log("碰到了(,就直接将该操作符输出到堆栈当中");
}
//如果扫描到的操作符是右括号“)”,将堆栈中的操作符导出(pop)到output中输出,直到遇见左括号“(”。将堆栈中的左括号移出堆栈(pop )。继续扫描下一个字符
else if (optarr[i] === this.data.idkhb) {
console.log("碰到了 )")
for (var j = InfixEXp.length - 1; j >= 0; j--) {
if (InfixEXp[j] === this.data.idkhk) {
console.log("直到遇见左括号“(”")
InfixEXp.pop();
break;
} else {
console.log("未遇到左括号前")
PostfixExp.push(InfixEXp[j]);
InfixEXp.pop();
console.log("此时栈顶元素为:" + InfixEXp[InfixEXp.length - 1]);
}
}
}
//如果扫描到的字符是一个操作符,分三种情况
else if (optarr[i] === this.data.idPlus || optarr[i] === this.data.idSub || optarr[i] === this.data.idMul || optarr[i] === this.data.idDiv) {
console.log("碰到了操作符");
//如果堆栈是空的或栈顶元素是‘(’,直接将操作符存储到堆栈中(push it)
if (InfixEXp.length === 0 || InfixEXp[InfixEXp.length - 1] === '(') {
console.log("此时堆栈是空的或栈顶元素是‘(’,直接将操作符存储到堆栈中");
InfixEXp.push(optarr[i]);
console.log("此时栈顶元素为:" + InfixEXp[InfixEXp.length - 1]);
}
//如果该操作符的优先级大于堆栈出口的操作符,就直接将操作符存储到堆栈中(push it)
else if ((optarr[i] === this.data.idMul || optarr[i] === this.data.idDiv) && (InfixEXp[InfixEXp.length - 1] === this.data.idPlus || InfixEXp[InfixEXp.length - 1] === this.data.idSub)) {
console.log("此时碰到的操作符的优先级大于堆栈出口的操作符:");
InfixEXp.push(optarr[i]);
console.log("经过处理此时栈顶元素为:" + InfixEXp[InfixEXp.length - 1]);
}
//如果该操作符的优先级低于或等于堆栈出口的操作符,就将堆栈出口的操作符导出(pop it), 直到该操作符的优先级大于堆栈顶端的操作符。将扫描到的操作符导入到堆栈中(push)
else {
console.log("碰到的操作符的优先级低于或等于堆栈出口的操作符,就将堆栈出口的操作符导出");
for (var j = InfixEXp.length - 1; j >= 0; j--) {
if ((optarr[i] === this.data.idMul || optarr[i] === this.data.idDiv) && (InfixEXp[InfixEXp.length - 1] === this.data.idPlus || InfixEXp[InfixEXp.length - 1] === this.data.idSub)) {
console.log("直到该操作符的优先级大于堆栈顶端的操作符");
InfixEXp.push(optarr[i])
break;
} else {
PostfixExp.push(InfixEXp[j]);
InfixEXp.pop();
}
}
InfixEXp.push(optarr[i]);
}
}
//如果扫描到的字符是操作数(如1、2等),就直接输出这些操作数。
else if (false === isNaN(optarr[i])) {
console.log("碰到了数字,直接将它入PostfisExp");
PostfixExp.push(optarr[i]);
}
}
//如果输入的中缀表达式已经扫描完了,但是堆栈中仍然存在操作符的时候,我们应该讲堆栈中的操作符导出并输入到output 当中
console.log("此时optarr已经空,但栈还有东西");
for (var j = InfixEXp.length - 1; j >= 0; j--) {
PostfixExp.push(InfixEXp[j]);
InfixEXp.pop();
}
三、后缀表达式的计算
/**
* 计算结果
*/
var result = 0.0;
//初始化一个空栈,用于计算
var resExp = [];
for (var i = 0; i < PostfixExp.length; i++) {
//如果被扫描的字符是一个二元运算符,那么就连续出栈两次,获得两个字符,元素出栈后,应用运算符进行计算,并将结果压栈
if (PostfixExp[i] == '+') {
result = Number(resExp[resExp.length - 1]) + Number(resExp[resExp.length - 2]);
resExp.pop();
resExp.pop();
resExp.push(result);
} else if (PostfixExp[i] === this.data.idSub) {
result = Number(resExp[resExp.length - 2]) - Number(resExp[resExp.length - 1]);
resExp.pop();
resExp.pop();
resExp.push(result);
} else if (PostfixExp[i] === this.data.idMul) {
result = Number(resExp[resExp.length - 1]) * Number(resExp[resExp.length - 2]);
resExp.pop();
resExp.pop();
resExp.push(result);
} else if (PostfixExp[i] === this.data.idDiv) {
result = Number(resExp[resExp.length - 2]) / Number(resExp[resExp.length - 1]);
resExp.pop();
resExp.pop();
resExp.push(result);
} else {
resExp.push(PostfixExp[i]);
}
}
result = Number(resExp[0]);