給定一個字符串計算式,計算結果

   面試的一個題,當時只說了算法思路和大概實現步驟,現在我把完整的做出來,嗯嗯嗯,不曉得我這樣算不算複雜,歡迎大家來建議,一起討論討論

給定一個計算式(包含加減乘除四則運算)字符串,計算結果

算法思想:

1)將操作數和操作符分別按順序存放到數組中

    此處我用到的方法是parseInt(str),此函數會返回字符串開頭的整數;然後用字符串截取第一個字符str.substring(0, 1)就是操作符,兩個步驟不能條換順序

2)遍歷操作符數組,先計算優先級較高的*和/,所以用Array.includes("*","/")判斷是否包含*和/,若有,找到一個,記住當前索引以及操作符就返回;

     記住當前索引既是爲了找到當前的操作符,也是爲了下一次遍歷不從頭開始,減小開銷

3)計算操作符原本相鄰的兩個操作數,進行相應的計算,存儲單步結果

     
 將計算過的兩個數從數組中刪除,將單步結果插入到該位置;操作符同理保證操作數運算順序不改變,操作符順序不改變;

4)返回計算最終結果

因爲最近在學習vue.js所以這個demo使用vue的相關語法寫的,也主要是爲了實時展現數據,方便。若大家有更好的方法,或對我的這個算法有建議,歡迎指教哦。qq:1358025287

同時大家也可以到我的GitHub下載源碼:

 

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>計算算式結果</title>
	<script src="./js/vue.js"></script>
</head>

<body>
	<div id="main">
		<label for="request">請輸入算式:</label><input type="text" name="request" id="" v-model="str">
		<button @click="reset">重置</button>
		<button @click="compute(str)">提交</button>
		<label for="result">結果:</label><input type="text" name="result" id="" v-model="result">
		<!-- 測驗我的nums,和op是否存儲成功 -->
		<!-- <div>操作數依次是:{{nums}}</div>
		<div>操作符依次是:{{op}}</div> -->

	</div>
	<script>
		var vm = new Vue({
			el: "#main",
			data: {
				str: '', //實時獲取輸入字符串
				result: '', //存放計算結果
				nums: [], //存放操作數
				op: [] //存放操作符
			},
			methods: {
				compute(str) {
					// console.log(str);
					//循環操作,將操作數和操作符分開
					while (str.length) {
						let num = parseInt(str);
						this.nums.push(num);
						let numstr = String(num);
						str = str.substr(numstr.length);
						// console.log(str);
						if (str.length != 0) {
							this.op.push(str.substring(0, 1));
							str = str.substr(1);
							// console.log(str);
						}
					}
					// console.log(this.nums, this.op);
					//找到‘*’或‘/’操作符
					let index = 0;
					let opr = '';
					let result;
					// console.log(111);
					//當op數組不爲空時調用searchOpr
					while (this.op.length > 0) {

						// 調用函數,找到對應的操作符以及索引
						let m = this.searchOpr(index, this.op);
						index = m[0];
						opr = m[1];
						// 計算結果
						if (opr === "*") {
							// 計算單步結果
							result = this.nums[index] * this.nums[index + 1];
							// 將計算了的兩個值從nums中刪除,
							this.nums.splice(index, 2);
							// 並將單步結果加入對應的位置,保證先後順序不亂
							this.nums.splice(index, 0, result);
							// 刪除計算了的操作符
							this.op.splice(index, 1);
							// console.log('*',this.nums,this.op);
						} else if (opr === "/") {
							result = this.nums[index] / this.nums[index + 1];
							this.nums.splice(index, 2);
							this.nums.splice(index, 0, result);
							this.op.splice(index, 1);
							// console.log('/',this.nums,this.op);
						} else if (opr === "+") {
							result = this.nums[index] + this.nums[index + 1];
							this.nums.splice(index, 2);
							this.nums.splice(index, 0, result);
							this.op.splice(index, 1);
							// console.log('+',this.nums,this.op);
						} else if (opr === "-") {
							result = this.nums[index] - this.nums[index + 1];
							this.nums.splice(index, 2);
							this.nums.splice(index, 0, result);
							this.op.splice(index, 1);
							// console.log('-',this.nums,this.op);
						}
					}
					this.result = result;
				},
				// 選擇操作符,並且找到操作符的索引
				// 遍歷操作符數組,先找到“*”和“/”,沒有的話就從數組開頭開始計算
				searchOpr(index, op) {
					let index1;
					let opr = '';
					if (op.includes("*", "/")) {
						for (let i = index; i < op.length; i++) {
							if (op[i] === "*") {
								opr = '*';
								index1 = i;
								break;
							} else if (op[i] === "/") {
								opr = '/';
								index1 = i;
								break;
							}
						}
					} else {
						index1 = 0;
						opr = op[0];
					}
					return [index1, opr];
				},
				// 點擊重置,清除我所有的數據,而不需要刷新頁面
				reset() {
					this.nums = [];
					this.op = [];
					this.result = "";
					this.str = "";
				}
			}
		});
	</script>
</body>

</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章