实数四则运算表达式的计算,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           for int  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() == 0 return  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 

 

转载于:https://www.cnblogs.com/felixfang/archive/2009/12/10/1621318.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值