首页 > 代码库 > 又一篇四则运算代码

又一篇四则运算代码

代码分为两段

一段为将输入分解为TOKEN :  0-9 ( ) + _ * /

一段为根据输入进行计算

 

第一段

技术分享
#include <iostream>#include <string>#include <vector>#include <deque>#include <tuple>#include <assert.h>using namespace std;enum CALC_STATUS{    InitStatus = 0,    InNumberStatus,    InIdentStatus,    EndLineStatus,    BadStatus};enum Token_Type{    NumberTokenType,    LparamTokenType,    RparamTokenType,    AddTokenType,    SubTokenType,    MulTokenType,    DivTokenType,    BadTokenType};typedef struct TOKEN_TUPLE{    TOKEN_TUPLE(const std::string& token,const Token_Type& type){        s = token;        t = type;    }    TOKEN_TUPLE(){};    TOKEN_TUPLE(const TOKEN_TUPLE& tt){        s = tt.s;        t = tt.t;    }    std::string s;    Token_Type t;};std::deque<TOKEN_TUPLE> tokenDeque;void InsertToken(const std::string& token,const Token_Type& type){    tokenDeque.push_front(TOKEN_TUPLE(token,type));}bool IsIdent(const char cc){    return ( cc == + ||             cc == - ||             cc == * ||             cc == / ||             cc == ( ||             cc == ) );}void InsertIdentToken(const std::string& token){    Token_Type tokenType = BadTokenType;    if(token.size() != 1 || !IsIdent(token[0]))        return;    if(token[0] == +){        tokenType = AddTokenType;    }else if(token[0] == -){        tokenType = SubTokenType;    }else if(token[0] == *){        tokenType = MulTokenType;    }else if(token[0] == /){        tokenType = DivTokenType;    }else if(token[0] == (){        tokenType = LparamTokenType;    }else if(token[0] == )){        tokenType = RparamTokenType;    }    InsertToken(token,tokenType);}bool ParseInput(const std::string& input){    bool bRet = false;    CALC_STATUS status = InitStatus;    size_t begPos , endPos ;    bool foundPoint = false;    tokenDeque.clear();    for(size_t index= 0;index < input.size();++index){        switch(status){        case InitStatus:            if(isspace(input[index])){                continue;            }else if(isdigit(input[index])){                status =  InNumberStatus;                begPos = index;                continue;            }else if( IsIdent(input[index]) ){                status =  InIdentStatus;                begPos = index;                continue;            }else{                status =  BadStatus;                //std::cout << "parse bad input,index is " << index << std::endl;                break;            }            break;        case InNumberStatus:            if(isdigit(input[index])){                status =  InNumberStatus;                continue;            }else if(input[index]==.){                if(foundPoint){                    status =  BadStatus;                    //std::cout << "parse bad input,index is " << index << std::endl;                    break;                }                status =  InNumberStatus;                foundPoint = true;                continue;            }else if( IsIdent(input[index])){                endPos = index;                InsertToken(input.substr(begPos,endPos-begPos),NumberTokenType);                begPos = index;                status =  InIdentStatus;                foundPoint = false;                continue;            }else if(isspace(input[index])){                endPos = index;                InsertToken(input.substr(begPos,endPos-begPos),NumberTokenType);                status =  InitStatus;                foundPoint = false;                continue;            }            else{                status =  BadStatus;                break;            }        case InIdentStatus:            endPos = index;            InsertIdentToken(input.substr(begPos,endPos-begPos));            status =  InitStatus;            --index;            continue;        default:            status =  BadStatus;            break;       }//switch(status)    }//for(size_t index= 0;index < input.size();++index)    if(status !=  BadStatus &&  status !=  InitStatus){        endPos = std::string::npos;        if(status == InNumberStatus)        {            InsertToken(input.substr(begPos,endPos-begPos),NumberTokenType);        }else if(status == InIdentStatus){            InsertIdentToken(input.substr(begPos,endPos-begPos));        }        bRet = true;    }else if(status ==  InitStatus){        bRet = true;    }    if(!bRet)        tokenDeque.clear();    return bRet;}void PrintErrorMsg(const string& input){    std::cout << std::endl << "test error!!" << std::endl;    std::cout << "input is " << input << "."<< std::endl;}void TestInput(const string& input,bool result,size_t tokenCount){    static int i = 1;    if( ParseInput(input) != result) {        PrintErrorMsg(input);        std::cout << "result is not  " << result << std::endl<< std::endl;    }else if( tokenDeque.size() != tokenCount ){        PrintErrorMsg(input);        std::cout <<"tokenCount is " <<tokenDeque.size() << " not  " << tokenCount << std::endl <<std::endl;    }else{        std::cout << i << "\ttimes test pass!" << std::endl;    }    i++;}bool GetNextToken(TOKEN_TUPLE& tokenTuple){    if(tokenDeque.empty()){        tokenTuple.t = BadTokenType;        return false;    }    tokenTuple = tokenDeque.back();    tokenDeque.pop_back();    return true;}void UngetToken(const TOKEN_TUPLE& tokenTuple){    tokenDeque.push_back(tokenTuple);}bool ParsePression(double& value);bool ParsePrimaryExpression(double& value){    bool ret = false;    bool minusFlag = false;    TOKEN_TUPLE tt;    GetNextToken(tt);    if (tt.t == SubTokenType) {        minusFlag = true;    } else {        UngetToken(tt);    }    GetNextToken(tt);    if(tt.t == NumberTokenType){        value = std::stod(tt.s);    }else if(tt.t == LparamTokenType){        if(!ParsePression(value))            return false;        GetNextToken(tt);        if(tt.t != RparamTokenType){            return false;        }    }else{        UngetToken(tt);//??    }    if(minusFlag)        value = -value;    ret =true;    return ret;}bool ParseTerm(double& value){    bool ret = false;    double v1;    double v2;    TOKEN_TUPLE tt;    if(!ParsePrimaryExpression(v1) )        return ret;    for(;;){        GetNextToken(tt);        if(tt.t != MulTokenType &&                tt.t != DivTokenType&&ret){            UngetToken(tt);            break;        }        ParsePrimaryExpression(v2);        if(tt.t == MulTokenType){            v1 = v1*v2;        }else if(tt.t == DivTokenType){            if(v2 ==0.0)                return ret;            v1 = v1/v2;        }    }    value = v1;    ret = true;    return ret;}bool ParsePression(double& value){    bool ret = false;    double v1;    double v2;    TOKEN_TUPLE tt;    if(tokenDeque.empty())        return ret;    if(!ParseTerm(v1))        return ret;    for(;;){        GetNextToken(tt);        if(tt.t != AddTokenType && tt.t != SubTokenType){            UngetToken(tt);            break;        }        ParseTerm(v2);        if(tt.t == AddTokenType){            v1 = v1+v2;        }else if(tt.t == SubTokenType){            v1 = v1-v2;        }else{            UngetToken(tt);        }    }    value = v1;    ret = true;    return ret;}int main(int argc, char *argv[]){//    std::string input;//    cin >> input;//    cout << input << endl;//    TestInput("2",true,1);//    TestInput("0.2",true,1);//    TestInput("2 3",true,2);    TestInput("2.467  + 3",true,3);    double d;    bool ret = ParsePression(d);//    TestInput("()2.467  + 3",true,5);//    TestInput("3.14 + ( 2.43-1) /3 *(2*6)",true,15);//    TestInput(".()2.467  + 3",false,0);//    TestInput("aas+2()2.467  + 3",false,0);//    TestInput("2.46.7  + 3",false,0);//    TestInput("2.4(6.7  + 3",true,5);    return 0;}
View Code

显示结果

技术分享

 

第二段

技术分享
  1 // 11111.cpp : 定义控制台应用程序的入口点。  2 //  3    4 #include "stdafx.h"  5 #include <string>  6 #include <iostream>  7    8    9 using namespace std; 10   11 std::string s1 = "2+3-2"; 12 std::string s2 = "2+3*3"; 13 std::string s3 = "2+(3*3)"; 14 std::string s4 = "()2+(3*3)"; 15   16 int gStringIndex = 0; 17   18 bool ParseExPression(const std::string& s, int& v); 19   20 #define ERROR_MSG    21 std::cerr << "Error. Func : " << __FUNCTION__ << ".\tLine : " << __LINE__ << std::endl;    22 std::cerr << "expression is " << s << ".  error index is " << gStringIndex << std::endl;   23 exit(0); 24   25   26 bool ParsePrimaryExpression(const std::string& s, int& v) 27 { 28     bool minusFlag = false; 29   30     if (s[gStringIndex] == -) { 31         minusFlag = true; 32         ++gStringIndex; 33     } 34   35     if (isdigit(s[gStringIndex])) { 36         std::string token = s.substr(gStringIndex, 1); 37         v = stoi(token); 38         gStringIndex++; 39         if (minusFlag) 40             v = -v; 41         return true; 42     } 43     else if (s[gStringIndex] == () 44     { 45         gStringIndex++; 46         if (!ParseExPression(s, v)) { 47             ERROR_MSG; 48         } 49         if (s[gStringIndex] == )) { 50             gStringIndex++; 51             if (minusFlag) 52                 v = -v; 53             return true; 54         } 55     } 56     else { 57         ERROR_MSG; 58     } 59           60   61   62   63     return false; 64 } 65   66   67 bool ParseTerm(const std::string& s, int& v) 68 { 69     int v1; 70     int v2; 71     char ident = 0; 72   73     if (!ParsePrimaryExpression(s, v1)) { 74         ERROR_MSG; 75     } 76     while (1) { 77         if (s[gStringIndex] != * && 78             s[gStringIndex] != /) 79         { 80             break; 81         } 82         else { 83             ident = s[gStringIndex]; 84             ++gStringIndex; 85         } 86   87         if (!ParsePrimaryExpression(s, v2)) { 88             ERROR_MSG; 89         } 90   91         if (ident == *) 92         { 93             v1 = v1*v2; 94         } 95         else if (ident == / && v2 != 0) { 96             v1 = v1 / v2; 97         } 98         else { 99             ERROR_MSG;100         }101     }102  103     v = v1;104     return true;105 }106  107 bool ParseExPression(const std::string& s, int& v)108 {109     int v1;110     int v2;111     char ident = 0;112  113  114     if (!ParseTerm(s, v1)) {115         ERROR_MSG;116     }117  118     while (1) {119         if (s[gStringIndex] != + &&120             s[gStringIndex] != -)121         {122             break;123         }124         else {125             ident = s[gStringIndex];126             ++gStringIndex;127         }128  129         if (!ParseTerm(s, v2)) {130             ERROR_MSG;131         }132  133         if (ident == +)134         {135             v1 = v1+v2;136         }137         else if (ident == -) {138             v1 = v1 - v2;139         }140         else {141             ERROR_MSG;142         }143  144     }145  146     v = v1;147     return true;148 }149  150  151 bool  ParseInput(const std::string& s)152 {153     gStringIndex = 0;154     int v;155     if (!ParseExPression(s, v)) {156         ERROR_MSG;157     }158          159     std::cout << s << " = " << v << endl;160  161  162     return true;163 }164  165 int main()166 {167     ParseInput(s1);168     std::cout << std::endl << std::endl;169  170     ParseInput(s2);171     std::cout << std::endl << std::endl;172  173     ParseInput(s3);174     std::cout << std::endl << std::endl;175  176     ParseInput(s4);177     std::cout << std::endl << std::endl;178  179     return 0;180 }
View Code

显示结果

2+3-2 = 3


2+3*3 = 11


2+(3*3) = 11

Error. Func : ParsePrimaryExpression. Line : 57
expression is ()2+(3*3). error index is 1

 

又一篇四则运算代码