实数四则运算表达式的计算,C++ 实现

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

 

posted on 2009-12-10 19:48  Felix Fang  阅读(2069)  评论(0编辑  收藏  举报

导航