• Calculator 2



    • 新增:

      • 计算类(拥有计算功能)

        • 采用符号优先级计算方法

        • 对符号不匹配的如 -2 ,自动补为 0-2

      • 计算内核信息

        • 输入 -a 可以显示等式与结果

        • 输入 -p 可以显示计算逐步过程

          • 传入 -a 参数 且 传入 -p 参数
          • 传入 -a 参数 且 不传入 -p 参数

    • 规定并非万无一失,但暂未发现有悖原意的bug。

    • 如有发现bug,但求一知,万分感谢。

    
    //
    //  main.cpp
    //  Calculator
    //
    //  Created by admin on 16/2/25.
    //  Copyright © 2016年 YooRarely. All rights reserved.
    //
    
    #include <iostream>
    #include <queue>
    #include <stack>
    #include <string>
    #include <cmath>
    #include <sstream>
    
    using namespace std;
    
    class Scan{
        
    private:
        bool err; // 输入是否出错
        
    public:
        // 字符是否为运算符
        bool isOper(char c){
            
            if ( c == '+' || c == '-' || c == '*' || c == '/' ) return true;
            return false;
        }
        // 字符是否为数字
        bool isCount(char c){
            
            if (c>='0' && c<='9') return true;
            return false;
        }
        
        queue <string> ToStringQueue(string input){
            err=false;
            queue <string > a;
            int sum_kuohao = 0;
            
            // 当输入未出错时遍历输入字符串
            for (int i = 0; i < input.size() && ! err; i ++){
                
                string s;
                
                // 如果为 运算符 或 括号
                if ( isOper( input[i] ) || input[i] == '(' || input[i] == ')' ) {
                    
                    s = input[i];
                    
                    if (!a.empty()){
                        
                    string k=a.back();
                        
                    if (input[i] == '(' && ( isCount( k[0] ) || k[0] == ')' ) ) err = true;
                    if ( isOper( k[0] ) && input[i] != '(' && input[i] != '-' ) err = true;
                        
                    }
                    
                    
                    if (input[i] == '(') sum_kuohao ++;
                    if (input[i] == ')') sum_kuohao --;
                    if ( sum_kuohao < 0 ) err = true;
                    
                }// 否则 如果为数字
                else if ( isCount( input[i] ) ){
                    
                    bool dian=false;
                    
                    while ( ! err && i < input.size() ){
                        if ( isCount( input[i] ) || input[i] == '.') s=s+input[i];
                        if ( input[i] == '.' ) {
                            
                            if ( dian ) err = true;
                            dian = true;
                            
                        }
                        
                        if ( isOper( input[i+1] ) || input[i+1] == '(' || input[i+1] == ')') break;
                        i++;
                    }
                    
                    if (dian && s[ s.size() - 1 ] == '.') err = true;
                    if ( s.size() > 10 ) err = true;
                    
                }
                // 入队
                a.push(s);
                s="";
            }
            if ( sum_kuohao ) err = true;
            
            if ( ! err && ! a.empty() ){
                
                string k = a.front();
                if ( isOper( k[0] ) && k[0] != '-' ) err = true;
                k = a.back();
                if ( isOper( k[0] ) ) err = true;
                
            }
            if ( err ) {
                
                while ( ! a.empty() ) a.pop();
                a.push("Error Input !");
                
            }
            return a;
        }
    };
    
    class Print{
    public:
        void PrintStringQueue(queue<string> a){
            
            while ( ! a.empty() ) {
                
                cout << a.front() << endl;
                a.pop();
            }
        }
    };
    
    
    
    
    
    
    class Calculate{
    private:
        bool print;
        int tried (stack <char> &oper,stack <int> &important,stack <double> &count, int k){
            
            while ( ! important.empty() && k <= important.top()){
                
                double amazing = count.top();
                count.pop();
                
                
                
                switch (oper.top()) {
                    case '+':
                        if (print) cout<<count.top()<<"+"<<amazing;
                        count.top() += amazing;
                        if (print) cout<<"="<<count.top()<<endl;
                        break;
                    case '-':
                        if (print) cout<<count.top()<<"-"<<amazing;
                        count.top() -= amazing;
                        if (print) cout<<"="<<count.top()<<endl;
                        break;
                    case '*':
                        if (print) cout<<count.top()<<"*"<<amazing;
                        count.top() *= amazing;
                        if (print) cout<<"="<<count.top()<<endl;
                        break;
                    case '/':
                        if (amazing == 0) { return -1;}
                        if (print) cout<<count.top()<<"/"<<amazing;
                        count.top() /= amazing;
                        if (print) cout<<"="<<count.top()<<endl;
                        break;
                }
                
                oper.pop();
                important.pop();
            }
            return 0;
        }
        
        
        
        
        
    public:
        // 字符是否为运算符
        bool isOper(char c){
            if ( c == '+' || c == '-' || c == '*' || c == '/' ) return true;
            return false;
        }
        // 字符是否为数字
        bool isCount(char c){
            if (c>='0' && c<='9') return true;
            return false;
        }
        
        double getAns(queue<string> a,bool p){
            
            stack <char> oper;
            stack <int> important;
            stack <double> count;
            int k=0;
            print=p;
            
            while ( ! a.empty() ){
                
                if (a.front()[0] == '(') k += 2;
                if (a.front()[0] == ')') k -= 2;
                
                if (isOper( a.front()[0] )){
                    
                    if ( oper.size() == count.size() ){
                        
                        count.push(0);
                        important.push(10000);
                        
                    }
                    else if ( a.front()[0] == '*' || a.front()[0] == '/'){
                        
                        if ( tried(oper, important, count, k+1) == -1 ) return 0.000000;
                        important.push(k+1);
                        
                    }
                    else{
                        
                        if ( tried(oper, important, count, k) == -1 ) return 0.000000;
                        important.push(k);
                        
                    }
                    oper.push( a.front()[0] );
                }
                if (isCount( a.front()[0] )){
                    
                    count.push( atof( a.front().c_str() ) );
                    
                }
                
                a.pop();
            }
            
            if ( ! oper.empty() )
                if ( tried(oper, important, count, -1) == -1 ) return 0.000000;
            return count.top();
        }
        
        
    };
    
    
    
    int main(int argc, const char * argv[]) {
        string input;
        bool p,a;
        double ans;
        int i;
        Scan scan;
        Print print;
        Calculate Calculate;
        
        p=false;
        a=false;
        i=1;
        
    //    getline(cin,input);
        
        if (argc<2) return 0;
        
        input=argv[i];
        
        while (1){
            
            if (input=="-a") {
                input=argv[++i];
                a=true;
                continue;
            }
            
            if (input=="-p"){
                input=argv[++i];
                p=true;
                continue;
            }
            
            break;
        }
        
    
    // print.PrintStringQueue( scan.ToStringQueue(input) );
        
        
        ans=Calculate.getAns( scan.ToStringQueue(input) , p);
        
        if (a) cout<<input<<"=";
        cout<<ans<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    jmeter压测学习42-逻辑控制器之交替控制器
    jmeter压测学习41-逻辑控制器之吞吐量控制器
    jmeter压测学习40-逻辑控制器之事务控制器
    jmeter压测学习39-获取post请求x-www-form-urlencoded格式的数据
    jmeter压测学习38-通过Jython调用Python脚本
    对微信小程序的生命周期进行扩展 – Typescript 篇
    在微信小程序开发中使用Typescript
    TCP长连接和短连接 Python代码
    jQuery Ajax编程
    Django 网页中文显示u开头的乱码
  • 原文地址:https://www.cnblogs.com/YooRarely/p/5392414.html
Copyright © 2020-2023  润新知