字符串-四则运算

题目大意:

    有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值。四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是1位(数值范围0~9)。另若有不能整除的情况,按向下取整处理,eg: 8/3得出值为2。若有字符串"8+7*2-9/3",计算出其值为19。

题目来源:

    2012年华为上机的一个题目

题目思路:

    建立栈分别存储操作符和操作数,比较操作符的优先级,并以此决定操作数是否进行出栈运算还是直接入栈。只要对给定字符串,画出出入栈的顺序,整个题基本没问题,只是过程比较繁琐。我在题目用到是C++的Stack容器,当然自己构造一个栈结构也可以。

 

源码:

#include <iostream>
#include <stack>
using namespace std;
int cmp(const char c1,const char c2)  //判断优先级
{
	if(c1==c2) //相同操作符,及同级操作符
		return 0;
	if((c1=='*'||c1=='/')&&(c2=='*'||c2=='/'))//同级
		return 0;
	
	if((c1=='*'||c1=='/')&&(c2=='+'||c2=='-'))//
		return 1;
	if((c1=='+'||c1=='-')&&(c2=='*'||c2=='/'))
		return -1;
	
	
}
int compute(const char* pstr) //计算结果
{
	stack<int> copnd; //存储操作数
	stack<char> copter; //存储操作符:+,-,*,/
	char cnum[512]; //存储提取的操作数
	int i=0;
	int len=strlen(pstr);
	int t1=0,t2=0,t3=0;//t1,t2:存储先后出栈的两操作数; t3:存储计算结果
	for(i=0;i<len;++i)
	{
		if(pstr[i]>='0'&&pstr[i]<='9') //提取操作数,注意操作数超过10时如何处理
		{
			int k=0,tn=0;
			while(isdigit(pstr[i])) 
				cnum[k++]=pstr[i++];
			cnum[k]='\0';
			tn=atoi(cnum);
			memset(cnum,0,sizeof(cnum));
			copnd.push(tn);
			cout<<"opnd: push("<<tn<<")"<<endl;
			i=i-1; //提取一个操作数完后,i已经指向下一位,需要重新调整,画图可以更好理解
		}
			
		else if(pstr[i]=='+'||pstr[i]=='-'||pstr[i]=='*'||pstr[i]=='/')
		{
			if(copter.empty()) //若栈为空,则直接将操作符入栈
			{
				copter.push(pstr[i]);//
				cout<<"opter: push("<<pstr[i]<<")"<<endl;
			}
			else 
			{
				
				switch(cmp(copter.top(),pstr[i]))
				{
				case 0: case 1: //同优先级操作符操作:先将操作数栈最顶层的两个元素出栈并根据操作符计算结果,然后将结果入操作数栈
					t1=copnd.top();
					cout<<"opnd: pop("<<t1<<")"<<endl;
					copnd.pop();
					t2=copnd.top();
					copnd.pop();
					cout<<"opnd: pop("<<t2<<")"<<endl;
					switch(copter.top())
					{
					case '+':
						t3=t2+t1;
						copnd.push(t3);
						cout<<"opnd: push("<<t3<<")"<<endl;
						break;
					case '-':
						t3=t2-t1;
						copnd.push(t3);
						cout<<"opnd: push("<<t3<<")"<<endl;
						break;
					case '*':
						t3=t2*t1;
						copnd.push(t3);
						cout<<"opnd: push("<<t3<<")"<<endl;
						break;
					case '/':
						if(t1==0) //零除情况要考虑
							return -1;//zero-divide
						t3=(int)(t2/t1);
						copnd.push(t3);
						cout<<"opnd: push("<<t3<<")"<<endl;
						break;
					default:break;

					}					
					copter.pop();	//同级操作符出栈				
					copter.push(pstr[i]); //同级操作符入栈				
					break;				
				case -1:
					copter.push(pstr[i]); //栈内操作符优先级小于所提取的操作符,则直接将提取的操作符入栈					
					break;
				default:break;
				}
			}
		}		
	}
	while(!copter.empty()) //当上述循环遍历至结尾时,至少最后的2个操作数未进行计算(至多3个操作数),可以画栈图理解
	{
		t1=copnd.top();
		copnd.pop();		
		t2=copnd.top();
		copnd.pop();		
		switch(copter.top())
		{
		case '+':
			t3=t2+t1;
			copnd.push(t3);			
			break;
		case '-':
			t3=t2-t1;
			copnd.push(t3);			
			break;
		case '*':
			t3=t2*t1;
			copnd.push(t3);			
			break;
		case '/':
			if(t1==0)
				return -1;//zero-divide
			t3=(int)(t2/t1);
			copnd.push(t3);			
			break;
		default:break;
		}		
		copter.pop();
	}	
	
	return t3;
}
int main()
{
	cout<<compute("42+4*2-82-5/2")<<endl;
	return 0;
}

 

posted @ 2013-09-12 14:47  ballwql  阅读(3003)  评论(0编辑  收藏  举报