• 第四次作业 计算器第二步


    题目链接:

    http://www.cnblogs.com/fzuoop/p/5326667.html

    github链接:

    https://github.com/MeKChen2/object-oriented/tree/master/Calculator-fourth homework

    1.解题思路:

    这次拿到的题目要求在第三次作业上进行修改,在看过学长在第三次作业上的评论后,我重新审了一次第三次的题目,发现我把题目理解错了。
    在将第三次作业的代码改成五个文件的时候,出现了很多问题,无论用什么编译器都无法正常将代码分成五个文件。
    所以,在进一步学习了栈的知识和浏览了许多博客后,我打算完全放弃第三次的代码来写第四次的作业。

    表达式的计算思路:

    1)准备两个栈:数据栈和运算符栈;反复读取表达式 。
    2)如果是数,入数据栈;
    3)如果是左括号,入运算符栈,如果是右括号,反复从运算符栈顶取运算符和从数据栈里取两个数据进行计算,并把结果入数据栈,直到遇到栈顶是左括号为止。
    4)如果是运算符op,先跟栈顶的运算符比,只要不高于栈顶优先级,就取出栈顶的运算符和数据栈的两个数据进行计算,并把结果入数据栈,直到高于栈顶运算符优 先级或者遇到左括号或者运算符栈空为止,此时把op入栈;
    5)处理栈中的运算符:取出栈顶的运算符和数据栈的两个数据进行计算,并把结果入数据栈,直到运算符栈空为止;
    6)这时数据栈中的数据就是计算结果。

    代码如下:
    #include <iostream>  
    #include <stack>  
    #include <string>
    #include <cstring> 
    using namespace std;  
       
    class Calculation
    {  
        private:  
            stack<char> oper;
            stack<double> shu;
            double v,a,b;
            char op; //运算符   
        public:  
            double calinput() //读取并计算表达式直到结束为止  
            {  
                do  
                {  
                    readdata();
                }  
                while(readop());
                calsurplus(); //处理栈中剩余的运算符 
                cout << v << endl;
                return 0;
            }   
              
            void readdata() //读取数据 
            {
                while(!(cin>>v))  //判断读取数据是否正常 
                {
                    cin.clear();
                    cin >> op;
                    oper.push(op);
                }  
                shu.push(v);
                return;
            }
            
            bool readop() //读取运算符   
            {   
                 while((op = cin.get()) == ')')  
                 {  
                    while( oper.top() != '(' )  
                    {  
                        b = shu.top(); 
                        shu.pop();   
                        a = shu.top();  
                        shu.pop();  
                        shu.push(cal(a, oper.top(), b)); //计算并入栈  
                        oper.pop(); //取走运算符   
                    }     
                    oper.pop();   
                 }  
                 if(op == '
    ')  
                 {  
                    return false;  
                 }  
                   
                 while(!oper.empty() && oper.top() != '(' && !com( op, oper.top()))  
                 {  
                    b = shu.top(); 
    				shu.pop();  
                    a = shu.top(); 
    				shu.pop();  
                    shu.push(cal( a, oper.top(), b )); //计算并入栈  
                    oper.pop(); //取走运算符    
                 }  
                   
                 oper.push(op);  
                 return true;  
            }   
              
            void calsurplus()
            {  
                while(!oper.empty())  
                {  
                    b = shu.top(); 
    		shu.pop();  
                    a = shu.top(); 
    		shu.pop();  
                    shu.push(cal( a, oper.top(), b )); //计算并入栈  
                    oper.pop(); //取走运算符   
                }  
    
                v = shu.top();  
                shu.pop();  
                return;  
            }  
            
            double cal(double a, char op, double b)  
            {  
    			if(op=='+')
    			    return a+b;
    			else if(op=='-')
    			    return a-b;
    			else if(op=='*')
    			    return a*b;
    			else if(op=='/')
    			    return a/b;
            }  
              
            bool com(char c, char d) //若c比d优先级高返回true,否则返回false   
            {  
                if(c != '+' && c != '-' && d != '*' && d != '/')
                	return true;
                else
                	return false;
            }  
              
    };  
      
    int main()  
    {  
        Calculation e;
        e.calinput();
        system("pause");  
        return 0;  
    } 
    

    运行结果:

    存在的问题:

    这部分代码无法满足题目要求,即当输入-a时要输出表达式,本想写完主要代码再进行-a那步骤的修改,想了很久没有想出方法。
    而且我定义的两个栈,一个是char,一个是double,所以没有用到sstream来将字符转换成数字。

    改进:

    剩下的三天时间,打算用其他方法再进行尝试,改进代码。

    反思:

    此次代码虽然没有通过第三次代码基础修改得到,但是这次我查阅学习了资料,自我感觉代码比之前第三次的要好了很多,第三次的代码用这次的方法也能更容易写出,现在来看第三次作业反而觉得很简单。以后的学习中应该先掌握好足够的知识,再进行做题,更有效果

    参考资料:

    http://www.nowamagic.net/librarys/veda/detail/2306
    http://blog.csdn.net/anye3000/article/details/7941231
    http://blog.sina.com.cn/s/blog_786ce14d01014ixq.html

    4.10更新版本二:

    #include <iostream>  
    #include <stack>   
    #include <string>  
    using namespace std;  
    const int SIZE = 100;  
      
    bool isOperator( char op )  
    {  
        switch(op)  
        {  
            case '+':  
            case '-':  
            case '*':  
            case '/':  
                return true;  
            default:  
                return false;  
        }  
    }  
      
    int check( char op )
    {  
        int value = -1;  
        switch(op)  
        {   
            case '(':  
                value = 0;  
                break;  
            case '+':  
            case '-':  
                value = 1;  
                break;  
            case '*':  
            case '/':  
                value = 2;  
                break;  
        }  
          
        return value;  
    }    
    
    int change( string str, char a[SIZE], int &len ,int &sum )  
    {  
    	// 中缀式转换为后缀式    	
        stack<char> oper;   
        oper.push('');  
        int i = 0;  
        int j = 0;  
          
        while( str[i] != '' )  
        {  
            if( str[i] >= '0' && str[i] <= '9' || str[i] == '.' )  
            {  
                a[j++] = str[i];  
                len++;  
            }   
            else if( str[i] == '(' ) 
            {  
                oper.push(str[i]);  
            }  
            else if( str[i] == ')' )   
            {  
                while( oper.top() != '(' )  
                {  
                   	a[j++] = oper.top();  
                    oper.pop();  
                    len++;  
                }  
                oper.pop(); 
            }  
            else if( i == 0 && (str[i] == '+' || str[i] == '-') && str[i+1] != 'a') //表明第一个数为正负号  
            {  
                a[j++] = str[i];  
                len++;  
            }
            else if( i == 2 && (str[i] == '+' || str[i] == '-') && str[i-1] == 'a') //表明当出现"-a"时第三个数为正负号  
            {  
                a[j++] = str[i];  
                len++;  
            }
    		else if( i == 0 && str[i] == '-' && str[i+1] == 'a' /*&& str[i+2] == ' '*/ )
            {  
                sum = 1;
            }
            else if( isOperator(str[i]) )  
            {  
                a[j++] = ' ';  //用空格隔开数  
                len++;    
                while( check(str[i]) <= check( oper.top() ) )  
                {  
                    a[j++] = oper.top();  
                    oper.pop();  
                    len++;  
                }  
                oper.push(str[i]); 
            }  
            i++;  
        }   
          
        while( oper.top() != '' )
        {  
            a[j++] = oper.top();  
            oper.pop();  
            len++;  
        }  
          
        return 0;  
    }  
      
    double read(char str[],int *i)    
    {    
        double x=0.0;    
        int k = 0;    
        while(str[*i] >='0' && str[*i]<='9')  // 处理整数部分    
        {    
            x = x*10+(str[*i]-'0');    
            (*i)++;    
        }    
        
        if(str[*i]=='.') // 处理小数部分    
        {    
            (*i)++;    
            while(str[*i] >= '0'&&str[*i] <='9')    
            {    
                x = x * 10 + (str[*i]-'0');    
                (*i)++;    
                k++;    
            }    
        }    
        while(k!=0)    
        {    
            x /= 10.0;    
            k--;    
        }    
        
        return x;    
    }    
      
      
    double calculate( char post[SIZE] )  
    {  
    	// 计算后缀表达式结果 
        stack<double> stack;   // 操作数栈   
        double x1 = 0;  
        double x2 = 0;  
        bool flag = false;  
        int i = 0;  
        double d = 0;  
          
        while( post[i] != '' )  
        {  
            if( post[i] >= '0' && post[i] <= '9' )  
            {  
                d =  read(post,&i);  
                if(flag) // 第一个数为负数  
                {  
                    d = -d;  
                    flag = false;  
                }  
                stack.push(d);  
            }   
            else if(post[i] == ' ' )  
                i++;    
            else if (post[i] =='+')    
            {    
                x2 = stack.top();    
                stack.pop();  
                x1 = stack.top();   
                stack.pop();  
                stack.push(x1+x2);    
                i++;    
            }    
            else if( post[i] == '-' && i == 0 ) //表明第一个数为负数,方便计算-1+2*3  
            {  
                flag = true;  
                i++;  
            }  
            else if (post[i] =='-')    
            {    
                x2 = stack.top();    
                stack.pop();  
                x1 = stack.top();  
                stack.pop();   
                stack.push(x1-x2);    
                i++;    
            }    
            else if (post[i] =='*')    
            {    
                x2 = stack.top();    
                stack.pop();  
                x1 = stack.top();    
                stack.pop();  
                stack.push(x1*x2);    
                i++;    
            }    
            else if (post[i] =='/')    
            {    
                x2 = stack.top();    
                stack.pop();  
                x1 = stack.top();    
                stack.pop();  
                stack.push(x1/x2);    
                i++;    
            }    
        }    
          
        return stack.top();   
    }  
      
    int main()  
    {  
        string str = "";
    	string str1 = ""; 
    	int i = 0;
    	int chang = 0;
        char a[SIZE];   
        cin >> str;
        chang = str.size();
        int len = 0;
    	int sum = 0;  
        change( str, a, len ,sum);  
        a[len] = '';
    	if(sum == 1)  
    	{
    		str1 = str.substr(2,chang-2); 
        	cout << str1 << "= " << calculate(a) << endl;
    	}
        else
        	cout << calculate(a) << endl;
        system("pause");  
        return 0;  
    } 
    

    运行结果:

    反思:

    换了一种方案后能够实现输入“-a”时输出表达式,通过把中缀表达式转换成后缀表达式进行计算。但代码仍有很多细节不符合题目要求,需要进一步修改。

  • 相关阅读:
    ip代理投票
    linq小笔记;
    c#类的执行顺序
    IEnumerable、GetEnumerator、IEnumerator的理解
    English随笔1
    AudioServicesPlaySystemSound音频服务—IOS开发
    iOS开发之压缩与解压文件
    xcode添加Cocos2d
    使用CoreTelephony获得SIM卡网络运营商名称
    iOS设备进行定位?
  • 原文地址:https://www.cnblogs.com/kurisu/p/5363700.html
Copyright © 2020-2023  润新知