zoukankan      html  css  js  c++  java
  • 字符串-四则运算

    题目大意:

        有字符串表示的一个四则运算表达式,要求计算出该表达式的正确数值。四则运算即:加减乘除"+-*/",另外该表达式中的数字只能是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]='';
    			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;
    }
    
  • 相关阅读:
    SmartSql = Dapper + MyBatis + Cache(Memory | Redis) + ZooKeeper + R/W Splitting + ......
    SmartSql For Asp.Net Core 最佳实践
    如何通过本地化事件正确实现微服务内部强一致性,事件总线跨微服务间最终一致性
    Netty入门搭建
    IO同步阻塞与同步非阻塞
    NIO的缓冲区、通道、选择器关系理解
    SpringBoot整合ActiveMQ
    ActiveMQ的介绍及使用
    nginx入门(一)
    垃圾回收器及tomcat调优
  • 原文地址:https://www.cnblogs.com/ballwql/p/3316894.html
Copyright © 2011-2022 走看看