牛客網 校招題 使用棧進行表達式求值

牛客網 校招題 使用棧進行表達式求值

簡單計算器

時間限制:1秒 空間限制:65536K 熱度指數:2762
校招時部分企業筆試將禁止編程題跳出頁面,爲提前適應,練習時請使用在線自測,而非本地IDE。

題目描述

讀入一個只包含 +, -, *, / 的非負整數計算表達式,計算該表達式的值。

輸入描述:

    測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字符,整數和運算符之間用一個空格分隔。沒有非法表達式。當一行中只有0時輸入結束,相應的結果不要輸出。

輸出描述:

    對每個測試用例輸出1行,即該表達式的值,精確到小數點後2位。
示例1

輸入

1 + 2
4 + 2 * 5 - 7 / 11
0

輸出

3.00
13.36
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>


using namespace std;

std::map<char, int> prio;


int fpow(int base,int exp){
	int ans=1;
	while(exp){
		if(exp&1)	ans*=base;
		base*=base;
		exp>>=1;
	}
	return ans;
}

double D2S(string a){
	double ans=0.0;
	int len=a.length();
	for(int i=len-1;i>=0;i--){
		ans+=(double)(a[i]-'0')*(double)fpow(10,len-1-i);
	}
	return ans;
}


double calc(double a,double b,char op){
	if(op=='+')
		return a+b;
	else if(op=='-')
		return a-b;
	else if(op=='/')
		return a/b;
	else if(op=='*')
		return a*b;
	return 0.0;
}

int main(int argc, char const *argv[])
{
	char str[500];
	prio['+']=prio['-']=1;
	prio['*']=prio['/']=2;
	while(gets(str)&&str[0]!='0'){
		stack<char> opcode;
		stack<double> oprand;
		int len=strlen(str);
		for(int i=0;i<len;i++){
			if(str[i]=='*'||str[i]=='/'||str[i]=='+'||str[i]=='-'){
				//opcode.push(str[i]);
				
				if(!opcode.empty()){
					//此處必須使用while循環將此時棧中所有可以先進行計算的有序對計算出結果
					//不能使用if,否則只能計算出棧頂一對的值,而此時棧中可以優先計算的對
					//將會在後續進行操作的時候失去從左到右計算的特性,而從左到右計算是中綴表達式的本質要求
					while(!opcode.empty()&&prio[str[i]]<=prio[opcode.top()]){
					//先計算的前提條件是當前運算符的優先級比棧中的優先級低
					//則此時計算棧中的序對不會再對後續的表達式造成影響
						double b=oprand.top();oprand.pop();
						double a=oprand.top();oprand.pop();
						//要注意ab的順序
						char t=opcode.top();
						opcode.pop();
						//printf("%lf %c %lf\n", a,t,b);
						oprand.push(calc(a,b,t));
					}
					opcode.push(str[i]);
				}
				else{
					opcode.push(str[i]);
				}
			}
			string tmp="";
			while(str[i]<='9'&&str[i]>='0'&&i<len){
				tmp+=str[i];i++;
			}
			if(tmp!=""){
				oprand.push(D2S(tmp));
				//cout<<oprand.top()<<endl;
			}

		}
		//到這裏棧中還會剩下最後一對,不要忘記
		while(!opcode.empty()){
			double a=oprand.top();oprand.pop();
			double b=oprand.top();oprand.pop();
			double t=calc(b,a,opcode.top());
			//printf("%lf %c %lf\n", b,opcode.top(),a);
			oprand.push(t);
			opcode.pop();
		}
		printf("%.2lf\n", oprand.top());
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章