1 //Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> //一个能处理四则运算的程序,实现语言C++,支持嵌套括号,可以处理实数,源码见下面: 2 #include<iostream> 3 #include <stdio.h> 4 #include <string.h> 5 6 #include<cmath> 7 using namespace std; 8 const int MAX=1000; 9 10 11 12 class Input 13 { 14 public: 15 Input() 16 { 17 for( int i = 0;i < MAX;i++ ) 18 Str_input[i] = '\0'; 19 } 20 char Str_input[MAX]; 21 }in; 22 23 24 class Output 25 { 26 public: 27 Output() 28 { 29 result = 0; 30 } 31 void getRes( double res ) 32 { 33 result = res; 34 } 35 double printRes() 36 { 37 // cout<<"这个表达式的结果为:"<<result<<endl; 38 return result; 39 } 40 private: 41 double result; 42 }; 43 44 template <class Type> 45 class STACK{ //定义栈类 46 private: 47 Type base[MAX]; 48 int Size; 49 public: 50 STACK(){Size=0;}; 51 void push(Type a) //入栈 52 { 53 base[Size]=a; 54 Size++; 55 } 56 Type pop() //出栈 57 { 58 return base[--Size]; 59 } 60 int size() 61 { 62 return Size; 63 } 64 }; 65 66 67 68 class Calculate_Cla 69 { 70 public: 71 bool IsData(char); 72 bool IsSym(char); 73 int IsPar(char); 74 bool Check(char *); 75 int setPri(char); //判断符号的优先极别 76 double ToData(char*); //把字符串转化为数值 77 double Call(double,double,char); //具体按符号计算 78 int GetMatch(char* buffer,int pos); //利用栈找到匹配的括号 79 void Opr( STACK<char>&, STACK<double>&, int& ); //利用栈计算 80 double Calculate(char*, double& ); //字符串的读入及调配 81 82 }; 83 bool Calculate_Cla::IsData(char ch) //判断输入计算的数字是否为0-9 添加科学计数法e 84 { 85 return ((ch>='0'&&ch<='9')||ch=='.'||ch=='e')?true:false;//添加科学计数法e 86 } 87 bool Calculate_Cla::IsSym(char ch) //判断是否输入非法运算符 88 { 89 return (ch=='+'||ch=='-'||ch=='*'||ch=='/')?true:false; 90 } 91 int Calculate_Cla::IsPar(char ch) //判断是否'()' 92 { 93 if(ch=='(') 94 return 1; 95 if(ch==')') 96 return -1; 97 return 0; 98 } 99 bool Calculate_Cla::Check(char *ch)//检验小数点个数,>1报错 l 100 { 101 int a=0; 102 for(int i=0;i<strlen(ch);i++) 103 if(ch[i]=='.') 104 a++; 105 if(a>1) 106 return false; 107 return true; 108 } 109 int Calculate_Cla::setPri(char ch) //符号的优先极别 110 { 111 switch(ch) 112 { 113 case '+': 114 return 0; 115 case '-': 116 return 0; 117 case '*': 118 return 1; 119 case '/': 120 return 1; 121 default: 122 return -1; 123 } 124 } 125 double Calculate_Cla::ToData(char* ch) //将数字转化为数值 126 { 127 int i,j,k,sumn=0; 128 double sum=0.0,p=0.0,q=0.0; 129 int summ=0;//科学计数法所表示的数据e 130 if(!Check(ch)) return 0.0; 131 for(i=0;i<strlen(ch);i++) //读入整数部分 132 { 133 if(ch[i]!='.') 134 sumn=sumn*10+(ch[i]-'0'); 135 else break; 136 } 137 if(strchr(ch, 'e')!=NULL)//判断是否为科学计数法e 138 {///////// 139 if(i<strlen(ch)) 140 for(j=i+1;j<strlen(ch);j++) //小数部分,到e为止 141 { 142 if(ch[j]!='e') 143 sum=sum*10+(ch[j]-'0'); 144 else break; 145 } 146 sum /= pow(10.0,(double)(strlen(ch)-6-i)); //有错 147 if(ch[j]=='e'&&j<strlen(ch)) 148 { 149 // if(ch[j]!='\0') //科学计数法部分e 150 for(k=j+2;k<=j+4;k++) 151 summ=summ*10+(ch[k]-'0');// ch[j]的ascii码减去0的ascii码 152 if(ch[j+1]=='-') 153 { 154 double p=(sum+sumn)/pow(10,summ); 155 return ((sum+sumn)/pow(10,summ)); //返回值 156 } 157 if(ch[j+1]=='+') 158 { 159 double q=(sum+sumn)*pow(10,summ); 160 return ((sum+sumn)*pow(10,summ)); 161 } 162 } 163 }///////////////// 164 else if(strchr(ch, 'e')==NULL)//如果不含科学计数法e 165 { 166 if(i<strlen(ch)) 167 for(j=i+1;j<strlen(ch);j++) //小数部分 168 sum=sum*10+(ch[j]-'0'); 169 sum /= pow(10.0,(double)(strlen(ch)-1-i)); 170 return (sum+sumn); //返回值 171 } 172 } 173 double Calculate_Cla::Call(double sum,double data,char ch) 174 { 175 double ans=0.0; 176 switch(ch) 177 { 178 case '+': 179 ans=sum+data; 180 break; 181 case '-': 182 ans=sum-data; 183 break; 184 case '*': 185 ans=sum*data; 186 break; 187 case '/': 188 if( data!=0.0 ) 189 ans=sum/data; 190 else 191 { 192 cout<<"程序出现除0错误,终止!\n"; 193 system("pause"); 194 exit(1); 195 } 196 break; 197 default:ans=0.0; 198 break; 199 } 200 return ans; 201 } 202 int Calculate_Cla::GetMatch(char* buffer,int pos) //利用栈找到匹配的括号 203 { 204 STACK<char> Temp; 205 int i; 206 for(i=pos;i<strlen(buffer);i++) 207 { 208 if(IsPar(buffer[i])==1)//左括号l 209 Temp.push('0'); 210 if(IsPar(buffer[i])==-1)//右括号l 211 { 212 Temp.pop();//出栈l 213 if(Temp.size()==0) return i; 214 } 215 } 216 return -1; 217 } 218 void Calculate_Cla::Opr(STACK<char>& symbol,STACK<double>& data,int& mark)//运算符操作l 219 { 220 double sum; 221 while(symbol.size()!=0)//运算符栈大小不为0,l 222 { 223 char tem=symbol.pop();//出栈l 224 int temp=setPri(tem);//优先级l 225 symbol.push(tem);//入栈l 226 if(temp<mark) 227 break; 228 else 229 { 230 sum=Call(data.pop(),data.pop(),symbol.pop()); 231 data.push(sum); 232 } 233 } 234 } 235 double Calculate_Cla::Calculate(char* buffer,double& sum) //字符串读入和各个函数调配 236 { 237 STACK<double> data; 238 STACK<char> symbol; 239 double ans; 240 char temp[MAX]; 241 int ct=0,mark=0,tp=0; 242 data.push(sum);//入栈l 243 while(ct<=strlen(buffer)) 244 { 245 if(IsData(buffer[ct])) //如果是数字或小数点 246 { 247 while( ct < strlen(buffer) && IsData(buffer[ct]) ) 248 { 249 temp[tp++]=buffer[ct++]; 250 } 251 if(temp[tp-1]=='e') 252 { 253 for(int k=0;k<=3;k++) 254 temp[tp++]=buffer[ct++]; 255 temp[tp]='\0'; 256 } 257 else temp[tp]='\0'; 258 tp=0; //读到非数字也非小数为止 259 ans=ToData(temp); //把读到的字符串转化为数 260 data.push(ans); //将数字存入栈中l 261 262 if(ct==strlen(buffer)) //已经独到字符串末尾 263 { 264 mark=0; 265 Opr(symbol,data,mark); //计算 266 sum=data.pop(); //此时data栈中还剩一个数据,即是结果 267 return sum; //返回结果 268 } 269 else 270 { 271 int mark=setPri(buffer[ct]); 272 Opr(symbol,data,mark); //计算 273 } 274 } 275 else if(IsSym(buffer[ct])&&buffer[ct-1]!='e') //如果是运算符且不为指数部分 276 symbol.push(buffer[ct++]); //运算符入symbol栈 277 else 278 { 279 char BF[100];int k=0; //如果都不是,则只能是括号 280 while( IsPar( buffer[ct] )!=1 && ct <= strlen(buffer) ) 281 BF[k++] = buffer[ct++]; 282 BF[k]='\0'; 283 if(IsPar(buffer[ct])==1) //一旦读到左括号,寻找它匹配的右括号 284 { 285 int i,j; 286 char Temp[100]; 287 for(i=ct+1,j=0;i<GetMatch(buffer,ct);i++,j++) 288 Temp[j]=buffer[i]; //把这对括号中的字符串存入Temp 289 Temp[j]='\0'; 290 data.push(Calculate(Temp,sum)); //递归调用Calculate直到没有括号 291 //然后开始计算,值层层返回最后将最终结果放入data栈 292 ct+=(strlen(Temp)+1); //跳过已经处理完的字符 293 if(ct+1==strlen(buffer)) //这里考虑字符串以括号结尾的情况 294 { 295 mark=0; 296 Opr(symbol,data,mark); 297 sum=data.pop(); 298 return sum; 299 } 300 else 301 { 302 mark=setPri(buffer[ct+1]); //不是的话继续计算 303 Opr(symbol,data,mark); 304 } 305 ct++; //读入下一个字符 306 } 307 } 308 } 309 return 0.; 310 } 311 312 313 314 class CheckStr 315 { 316 public: 317 static int check( char *str ) 318 { 319 int i; 320 STACK<char> Temp; 321 for( i = 0;i < strlen(str);i++ ) 322 { 323 char t = str[i]; 324 if( !( (int(str[i]) <= 57 && int(str[i]) >= 48) || str[i]=='(' || str[i]==')' || str[i]=='*' 325 || str[i]=='+' || str[i]=='-' || str[i]=='/' || str[i]=='.'||str[i]=='e') ) //检测是否含有非法字符 添加科学计数法e 326 return 2; 327 else if( str[i]=='(' ) 328 Temp.push('0'); 329 else if( str[i]==')' ) 330 { 331 if( Temp.size()<=0 ) //检测括号是否匹配,右括号是否过多 332 return 1; 333 else 334 Temp.pop(); 335 } 336 } 337 if( Temp.size()!=0 ) //检测括号是否匹配,左括号是否过多 338 return 1; 339 return 0; 340 } 341 }; 342 343 double function(char*Str_input)//Str_input代入equation[][] 344 { 345 double sum=0.0; 346 cout.precision(12); 347 348 Calculate_Cla cl; 349 Output out; 350 351 while(1) 352 { 353 Str_input;//输入模块 354 int res = CheckStr::check(Str_input); //判断模块 in.Str_input 355 if( res == 0 ) 356 break; 357 else if( res == 1 ) 358 cout<<"输入字符串括号不匹配,请重新输入:\n"; 359 else if( res == 2 ) 360 cout<<"输入字符串有非法字符,请重新输入:\n"; 361 else 362 {} 363 } 364 out.getRes( cl.Calculate(Str_input,sum) ); //计算模块 365 // out.printRes(); //输出模块 366 system("pause"); 367 // return 0; 368 return out.printRes(); 369 } 370 void main() 371 { 372 char *fun="12.3e-001+(-4.56e+002)"; 373 // char *fun="1.23+(-456)"; 374 double C=function(fun); 375 cout<<"这个表达式的结果为:"<<C<<endl; 376 }