JS 实现个位数四则运算

四则运算式,先乘除后加减
数 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
喜欢就支持一下吧
点赞0 分享