四则运算

#include <iostream>
#include <math.h>
#include <stack>
using namespace std;

const int n=100;                                        //设置运算符的个数

class operation
{
private:
 char   str_data[n];                                  //存储四则运算的表达式 
 //float  x_data[n];                                    //存储表达式的数据
 //char   s_sign[n];                                    //存储表达式的运算符号
 int    check_input_data();                           //检查输入表达式的正确性
 void   input_data();                                 //输入四则运算的表达式
 void   insert_buff(char* p1,char* p2,char* buff);    //把原字符串str_data中p1到p2之间的数据用buf替换(包括p1和p2)
 char*  check_bra_mat(char* p1,char* p2,char* bra_grade);//验证等级匹配的正确性,在这里等级指括号
 double calculate_in_bra_data(char*,char*);           //计算不带括号的四则运算
public: 
 operation(){};
 ~operation(){}; 
 int    calculate_data();                             //计算带括号的四则运算 
};
//
//
//operation::check_input_data():检查输入表达式str_data的正确性
//
//
int operation::check_input_data()
{
 char* now;
 int num=0;
 stack<char>bra_stack;
 now=str_data;
 //表达式正确性的检测
 while(*now!='/0')                                         
 {
  int dot_check=0;
  char* now_copy,*bra="0123456789+-*/^()[]{}.";
  //输入"0123456789+-*/^()[]{}."以外的符号错误
  if(!strchr(bra,*now))   
   cout<<++num<<":表达式中“"<<now<<"”出现错误字符!/n";
  //检测*now是否为最后一个字符
  if(*(now+1)!='/0')//如果不是,则检测*now和*(now+1)的关系
  {

//zxg于2007.4.12修改了表达式符号匹配的错误   
   //"+-*/^."与"+-*/^."在一起错误
   /*
            if(strchr("+-/*^.",*now)&&strchr("+-/*^.",*(now+1)))
                cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
   */

   //"+-*/^."与"*/^."在一起错误
   if(strchr("+-*/^.",*now)&&strchr("*/^.",*(now+1)))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
   //"+-*/^."三个符号的组合错误,如"+++"、"++-"
   if(*(now+2)!='/0')
    if(strchr("+-*/^.",*now)&&strchr("+-*/^.",*(now+1))&&strchr("+-*/^.",*(now+2)))
     cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";

//zxg于2007.4.12修改了表达式符号匹配的错误
   //"([{"与"+-*/^."在一起错误
   /*
   if(strchr("([{",*now)&&strchr("+-/*^.",*(now+1)))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
   */

   //"([{"与"*/^."在一起错误
   if(strchr("([{",*now)&&strchr("*/^.",*(now+1)))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";


   //"([{"与")]}"在一起错误
   if(strchr("([{",*now)&&strchr(")]}",*(now+1)))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
   //"+-*/^"与")]}"在一起错误
   if(strchr("+-*/^",*now)&&strchr(")]}",*(now+1)))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
   //")]}"与'.'在一起错误
   if(strchr(")]}",*now)&&(*(now+1)=='.'))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
  }
  else//如果是
  {
   //表达式最后为"+-*/^"错误
   if(strchr("+-*/^",*now))
    cout<<++num<<":表达式中“"<<now<<"”输入错误!/n";
  }
  //表达式中的每个数字有两个以上点号错误。如"123.5.45"
  if(isdigit(*now)||*now=='.')
  {
   now_copy=now;
   while(isdigit(*now)||*now=='.')
   {    
    if(*now=='.')
     dot_check++;
    if(dot_check>1)
     cout<<++num<<":表达式中“"<<now_copy<<"”数字输入错误!/n";
    now++;
   }   
   continue;
  }  
  //检查括号匹配的正确性
  if(strchr("([{",*now))
   bra_stack.push(*now);
  if(strchr(")]}",*now))
  {
   char ch;
   switch(*now)
   {
   case ')':     ch=*now-1;
    break;
   case ']':     ch=*now-2;
    break;
   case '}':     ch=*now-2;
    break;
   };
   if((!bra_stack.empty())&&(ch==bra_stack.top()))    
    bra_stack.pop();
   else
    cout<<++num<<":表达式中“"<<now<<"”括号匹配错误!/n";
  };   
  now++;  
 };
 if(num==0)
  return 0;
 else
  return 1;
}
//
//
//operation::input_data():输入四则运算的表达式
//
//
void operation::input_data()
{
  
 cout<<"输入四则运算的表达式:";      //输入四则运算的表达式
 cin>>str_data;
 system("cls");
}
//
//
//operation::calculate_in_bra_data():计算不带括号的四则运算
//
//
double operation::calculate_in_bra_data(char* p1,char* p2)
{
 float x_data[n];                     //存储表达式的数据
 char s_sign[n];//mid[n];             //s_sign[n]存储表达式的运算符号
 int mi=0,i=0;
 while(p1<=p2)                      //把()里面的四则运算表达式转化为数字x_data[n]和运算符号s_sign[n]
 {
//zxg于2007.4.12修改了表达式的存储操作
  x_data[i]=atof(p1);
  do
  {
   p1++;
  } while(strchr("+-*/^",*p1)==NULL);
  s_sign[i]=*p1;
  p1++;
  i++;


  /*
  if(isdigit(*p1)||*p1=='.')
  {
   mid[mi]=*p1;
   mi++;
  }
  else
  {
   s_sign[i]=*p1;
   if(mi!=0)
   {
    mid[mi]='/0';
    x_data[i]=atof(mid);    
    for(int mii=0;mii<100;mii++)
     mid[mii]='/0';
    mi=0;
   };
   i++;
  };
  p1++;
  */
 };
 i--;
 //x_data[i]=atof(mid);
 char* grade_set[3]={"^","*/","+-"};              //grade_set为计算等级的设定:'^'为0级;'*'和'/'为1级;'+'和'-'为2级
 for(int grade=0;grade<3;grade++)                 //grade为计算的等级(等级的优先级为从小到大)
  for(int j=0;j<i;j++)
   if(strchr(grade_set[grade],s_sign[j]))
   {
    switch(s_sign[j])                         //按照设定的计算等级进行四则运算
    {
    case '+':   x_data[j]=x_data[j]+x_data[j+1];
     break;
    case '-':   x_data[j]=x_data[j]-x_data[j+1];
     break;
    case '*':   x_data[j]=x_data[j]*x_data[j+1];
     break;
    case '/':   x_data[j]=x_data[j]/x_data[j+1];
     break;
    case '^':   x_data[j]=pow(x_data[j],x_data[j+1]);
     break;
    default:
     cout<<"输入的表达式有误!"<<endl;
    };
    //运算后对数据进行重新的整理,如果计算的是数组最后的数据,那可以不必进行整理,如计算2+3*6中的3*6。
    if(j!=i-1)
     for(int ij=j;ij<i-1;ij++)
     {
      x_data[ij+1]=x_data[ij+2];               //数字的前移
      s_sign[ij]=s_sign[ij+1];                 //计算符号的前移      
     };    
    i--;
    j=-1;        
   };
 return x_data[0];        //x_data[0]最后为整个()里面的值
}
//
//
//dtoa():把double型数转化为字符串
//
//
char* dtoa(double f,char str[])
{
 sprintf(str, "%.2f", f);             //修改计算的精度
 return str;
}
//
//
//operation::check_bra_mat():验证等级匹配的正确性,在这里等级指括号
//
//
char* operation::check_bra_mat(char* p1,char* p2,char* bra_grade)
{
 char *p;
 p=strchr(p1+1,* bra_grade);
 while(p!=NULL)
 {
  if(p>p2)
   return p1;
  p1=p;
  p=strchr(p1+1,* bra_grade);
 }; 
 return p1;
}
//
//
//operation::insert_buff():把原字符串str_data中p1到p2之间的数据用buf替换(包括p1和p2)
//
//
void operation::insert_buff(char* p1,char* p2,char* buf)
{
 char p[100];
 int i=p1-str_data;                       //计算p1指针在字符串str_data中的位置
 strcpy(p,p2+1);                          //保存p2指针以后的表达式
 int j=0;
 while(buf[j]!='/0')                      //把()内的表达式用其计算结果代替,并存储到字符串str_data相应的位置。注意包括()
 {
  str_data[i]=buf[j];
  i++;
  j++;
 }
 j=0;
 while(p[j]!='/0')                        //把p2以后的内容保存到字符串str_data中
 {
  str_data[i]=p[j];
  i++;
  j++;
 }
 str_data[i]='/0';
}
//
//
//operation::calculate_data():计算带括号的四则运算
//
//
int operation::calculate_data()
{
 double num_in;
 char* bra_grade="()[]{}",*p1,*p2,contin;
 do
 {  
  input_data();
  cout<<" "<<str_data<<endl;
  if(check_input_data())
  {
   contin='y';
   continue;
  }
  while(* bra_grade!='/0')             //用来判断四则混合运算是否计算完
  {
   p1=strchr(str_data,* bra_grade); //搜索现有等级的运算的起始位置,如要运算()等级的运算,则p1指向'('的位置
   while(p1!=NULL)                  //判断现有等级的运算是否完成
   {
    p2=strchr(p1+1,* (bra_grade+1));         //搜索现有等级的运算的终止位置,如要运算()等级的运算,则p2指向')'的位置
    p1=check_bra_mat(p1,p2,bra_grade);       //验证等级匹配的正确性,在这里等级指括号
    num_in=calculate_in_bra_data(p1+1,p2-1); //计算现有等级的运算结果,如要运算()等级的运算,则num_in为()内的运算结果
    char buf[100];
    dtoa(num_in,buf);                //把num_in转为字符串
    int i=0;
    insert_buff(p1,p2,buf);                  //把原字符串str_data中p1到p2之间的数据用buf替换(包括p1和p2)
    p1=strchr(str_data,'(');                 //搜索现有等级的运算的下一个起始位置
    cout<<"="<<str_data<<endl;
   };
   bra_grade=bra_grade+2;           //如果现有等级的运算计算完毕,则计算下一等级
  };
  p1=str_data;                         //如果所有括号内的计算完毕,则剩下一个纯四则的表达式,再计算一次
  p2=strchr(str_data,'/0');
  num_in=calculate_in_bra_data(p1,p2-1);
  cout<<"="<<num_in<<endl<<endl<<endl; //得出最终结果
  cout<<"表达式已经计算完毕!是否继续(y/n)?"<<endl;
  cin>>contin;
  //gets();
  while(contin!='y'&&contin!='Y'&&contin!='n'&&contin!='N')
  {
   cout<<"您的输入有误!"<<endl;
   cout<<"表达式已经计算完毕!是否继续(y/n)?"<<endl;
   cin>>contin;
   //gets();
  };
  if(contin=='y'||contin=='Y')
   system("cls");
 }while(contin=='y'||contin=='Y');        //判断用户是否继续
 return 1;

void main()
{
 operation s;   
 s.calculate_data();
 //system("pause");
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxg623

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值