Calculator

  • github 地址 :https://github.com/YooRarely/object-oriented.git

    • 由于代码的注释过于详细,就不对代码再进行解释了 (如有疑问可以在评论内询问)

    • 支持带空格的式子,以及带各种诡异字符的式子。。(会自动忽略)

    • 增添了之前 写的四则运算中 的没有涉及的判错。。

    • 之前 写的四则运算 把 处理 字符串 和 运算 冗杂在一起 降低了 运算过程的可读性 修改起来也相当麻烦,于是重写

    • 虽然 只有获取字符串队列的功能 但是稍作修改就能将此运用于之前的运算中去


	//
	//  main.cpp
	//  Calculator
	//
	//  Created by admin on 16/2/25.
	//  Copyright © 2016年 YooRarely. All rights reserved.
	//
	
	#include <iostream>
	#include <queue>
	#include <string>
	
	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){
	        // 初始化变量  a 为 返回值
	        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 ++; // 左括号 数量+1
	                if (input[i] == ')') sum_kuohao --; // 右括号 数量-1
	                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;
	                
	                // 如果这个数超过10位 错误
	                if ( s.size() > 10 ) err = true;
	                
	            }
	            
	            // 入队
	            a.push(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;
	        }
	        // 如果存在错误 把 a 队列清空 报告错误
	        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();
	        }
	    }
	};
	
	
	int main(int argc, const char * argv[]) {
	    string input;
	    getline(cin,input);
	    Scan scan;
	    Print print;
	    print.PrintStringQueue( scan.ToStringQueue(input) );
	    
	    return 0;
	}

  • 原来是拿着之前写的进行修改

  • 分成两个存储运算符和数字的队列

  • 除了增加判断小数以外其他都弄好了。。

  • 但是感觉用起来麻烦且不好扩展,于是就拍掉重做。。

  • hpp 文件


		//
		//  scan.hpp
		//  text
		//
		//  Created by admin on 16/2/25.
		//  Copyright © 2016年 YooRarely. All rights reserved.
		//
		
		#ifndef scan_hpp
		#define scan_hpp
		
		#include <stdio.h>
		#include <string>
		#include <iostream>
		#include <queue>
		
		using namespace std;
		
		class scan{
		    
		private:
		    deque <int> important;
		    deque <char> oper;
		    deque <int> count;
		    queue <string> str;
		    int k;
		    bool err;
		    
		public :
		    void ToStringQueue(string input);
		    void print(){
		        if (isErr()){
		            std::cout << "input is error!" << std::endl;
		            return;
		        }
		        int f = 1,j = 0;
		        for (int i = 0; i < oper.size(); i++){
		            while ( important[i] != f ){
		                std::cout << count[j++] << std::endl;
		                f++;
		            };
		            std::cout << oper[i] << std::endl;
		              f++;
		        }
		        if (j < count.size())  std::cout << count[j++] << std::endl;
		    }
		    bool isErr() { return err; }
		};
		
		
		#endif /* scan_hpp */

  • cpp 文件


		//
		//  scan.cpp
		//  text
		//
		//  Created by admin on 16/2/25.
		//  Copyright © 2016年 YooRarely. All rights reserved.
		//
		
		#include "scan.hpp"
		
		void scan:: ToStringQueue(string input){
		    err=false;
		    while ( ! oper.empty() ) oper.pop_back();
		    while ( ! count.empty() ) count.pop_back();
		    while ( ! important.empty() ) important.pop_back();
		    k = 0;
		    int count = 0;
		    int biubiubiu = -1;
		    for (int i = 0; i < input.length() && ! err; i ++){
		        switch (input[i]) {
		            case '(':
		                if (biubiubiu == 0) err = true; oper.push_back('('); important.push_back( ++ k); count = 0; biubiubiu = 1;
		                break;
		            case ')':
		                if (biubiubiu > 2) err = true; oper.push_back(')'); important.push_back( ++ k); count = 0; biubiubiu = 2;
		                break;
		            case '+':
		                if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('+'); important.push_back( ++ k); count = 0; biubiubiu = 3;
		                break;
		            case '-':
		                if (biubiubiu > 2) err = true; oper.push_back('-'); important.push_back( ++ k); count = 0; biubiubiu = 4;
		                break;
		            case '*':
		                if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('*'); important.push_back( ++ k); count = 0; biubiubiu = 5;
		                break;
		            case '/':
		                if (biubiubiu > 2 || biubiubiu == 1) err = true; oper.push_back('/'); important.push_back( ++ k); count = 0; biubiubiu = 6;
		                break;
		            default:
		                break;
		        }
		        if (input[i] >= '0' && input[i] <= '9') {
		            
		            if (!this->count.empty() && ! biubiubiu) this->count.pop_back(),k --;
		            
		            biubiubiu = 0;
		            
		            if (1L + count * 10 + input[i] - 48 > 9999999999L) err = true;
		            
		            count = count * 10 + input[i] - 48;
		            
		            k ++;
		            
		            this->count.push_back(count);
		            
		        }
		    }
		    if ( k == important.back() && oper.back() != ')') err = true;
		    int check=0;
		    for (int i = 0 ; i < oper.size(); i ++){
		        if (oper[i] == '(') check++;
		        if (oper[i] == ')') check--;
		        if (check < 0) err = true;
		    }
		    if (check > 0) err = true;
		
		}

posted on 2016-02-25 19:48  YooRarely  阅读(167)  评论(0编辑  收藏  举报

导航