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