Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1500991
  • 博文数量: 213
  • 博客积分: 10418
  • 博客等级: 上将
  • 技术积分: 3358
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-09 23:49
文章分类

全部博文(213)

文章存档

2014年(1)

2013年(5)

2012年(11)

2011年(2)

2010年(8)

2009年(26)

2008年(160)

分类: C/C++

2008-04-11 00:29:16

 

#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<<":表达式中“"<   */


   
//"+-*/^."与"*/^."在一起错误

   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<<":表达式中“"<   */


   
//"([{"与"*/^."在一起错误

   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");
}

阅读(721) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~