四则运算式,先乘除后加减
数 0~9,+-*/,没有括号
1. 算法思路
低优先级操作符遇到其右侧高优先级操作符,右侧优先运算
相同优先级的操作符,左侧优先运算
高优先级操作符遇到其右低优先级操作符,左侧优先运算
2. 数据结构采用栈结构
3. 单元测试
let x = '3+2*3+6/3+6/2+9/3+5*3-8'
// 操作符优先级 0 ~ 1
let OPERATOR = [['+', 0], ['-', 0], ['*', 1], ['/', 1]]
function run (x) {
let nArr = []
let oArr = []
let iRet = ''
let i = 0 // 头指针
let sNToken = x.charCodeAt(i) - 48
let sPToken = ''
let nPriority = 0
if (sNToken < 0 || sNToken > 9) {
iRet = `Error at position ${i} : is not a number(${x.charAt(i)})!`
} else {
nArr.push(sNToken)
i = 1
for (; i < x.length - 1 ;) {
// 获取操作符
sPToken = x.charAt(i);
// 验证操作符,获取优先级
nPriority = validateOperator(sPToken)
if (typeof nPriority !== 'number') {
iRet = `nPriority at position ${i}`
break
}
// 获取第二个数
sNToken = x.charCodeAt(i + 1) - 48
if (sNToken < 0 || sNToken > 9) {
iRet = `Error at position ${i + 1} : is not a number(${x.charAt(i + 1)})!`
}
// 比较 优先级
(typeof(iRet = stackOut(oArr, nArr, false, nPriority)) == 'string') ? true : iRet = '';
if (iRet) {
break
}
// 压栈
nArr.push(sNToken)
let opPair = []
opPair[0] = sPToken
opPair[1] = nPriority
oArr.push(opPair)
i += 2
}
(typeof(iRet = stackOut(oArr, nArr, true)) == 'string')?true:iRet='';
}
if (iRet) {
console.log(iRet)
} else {
nRet = nArr.pop()
}
return nRet
}
function stackOut (oArr, nArr, bIsNotCareAboutPriority, nPriority) {
let iRet = ''
// 操作符栈顶元素的优先级是否大于当前优先级
//let flag = oArr.length != 0 && (bIsNotCareAboutPriority || oArr[oArr.length - 1][1] >= nPriority)
while (oArr.length != 0 && (bIsNotCareAboutPriority || oArr[oArr.length - 1][1] >= nPriority)) {
// 弹栈计算
let n
let n2 = nArr.pop()
let n1 = nArr.pop()
let op = oArr.pop()[0]
n = calculate(op, n1, n2)
if (typeof n !== 'number') {
iRet = n;
} else {
nArr.push(n)
}
}
return iRet === '' ? true : iRet
}
function calculate (op, n1, n2) {
let n;
let iRet = ''
switch (op) {
case '+': n = n1 + n2; break;
case '-': n = n1 - n2; break;
case '*': n = n1 * n2; break;
case '/': n = n1 / n2; break;
default:
iRet = `Error in calculate ${op}`
console.log(iRet)
break
}
if (iRet !== '' && (!isFinite(n) || isNaN(n))) {
iRet = 'Error, the result is invalid'
}
return iRet === '' ? n : iRet
}
function validateOperator (sPToken) {
let iRet = ''
let j = 0
for (j = 0; j < OPERATOR.length; j++) {
if (OPERATOR[j][0] == sPToken) {
break
}
}
if (j >= OPERATOR.length) {
iRet = `Error: Syntax error: invalid operator "${sPToken}"`
}
return iRet === '' ? OPERATOR[j][1] : iRet
}
console.log(run(x))
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END