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