zoukankan      html  css  js  c++  java
  • 又一篇四则运算代码

    代码分为两段

    一段为将输入分解为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 << "	times 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__ << ".	Line : " << __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

    显示结果

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    TimeVal类——Live555源码阅读(一)基本组件类
    QT国际化 一 (lupdate/linguits/lrelease)
    qmake的使用
    将Apache加入到linux系统service
    ubuntu下编译VLC
    Ubuntu14.04安装intel集显驱动
    net-snmp的dateandtime数据类型
    MySQL的主从复制原理
    【iOS开发-25】UIDevice查看系统信息,从一个问题開始怎样高速找到自己想要的属性和方法并看懂它
    POJ 3279 Fliptile (二进制+搜索)
  • 原文地址:https://www.cnblogs.com/itdef/p/7106101.html
Copyright © 2011-2022 走看看