1. 程式人生 > >又一篇四則運算代碼

又一篇四則運算代碼

while mage nts == ace ron found ios cer

代碼分為兩段

一段為將輸入分解為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

又一篇四則運算代碼