zoukankan      html  css  js  c++  java
  • 第四次作业 计算器第二步

    题目链接:

    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”时输出表达式,通过把中缀表达式转换成后缀表达式进行计算。但代码仍有很多细节不符合题目要求,需要进一步修改。

  • 相关阅读:
    MDX Step by Step 读书笔记(六) Building Complex Sets (复杂集合的处理) Filtering Sets
    在 Visual Studio 2012 开发 SSIS,SSAS,SSRS BI 项目
    微软BI 之SSIS 系列 在 SSIS 中读取 SharePoint List
    MDX Step by Step 读书笔记(五) Working with Expressions (MDX 表达式) Infinite Recursion 和 SOLVE_ORDER 原理解析
    MDX Step by Step 读书笔记(五) Working with Expressions (MDX 表达式)
    使用 SQL Server 2012 Analysis Services Tabular Mode 表格建模 图文教程
    MDX Step by Step 读书笔记(四) Working with Sets (使用集合) Limiting Set and AutoExists
    SQL Server 2012 Analysis Services Tabular Model 读书笔记
    Microsoft SQL Server 2008 MDX Step by Step 学习笔记连载目录
    2011新的开始,介绍一下AgileEAS.NET平台在新的一年中的发展方向
  • 原文地址:https://www.cnblogs.com/kurisu/p/5363700.html
Copyright © 2011-2022 走看看