c++实现的完整功能计算器.docx
《c++实现的完整功能计算器.docx》由会员分享,可在线阅读,更多相关《c++实现的完整功能计算器.docx(8页珍藏版)》请在冰豆网上搜索。
c++实现的完整功能计算器
一些说明:
本程序支持基本的四则运算,三角函数运算(sin,cos,tan),指数运算,以及对数运算(lg,ln,log),取模运算,同时还支持括号!
主函数流程:
输入运算式子->判断是否有异常字符->对式子进行处理以便于计算->调用计算没有括号的式子的函数去除括号,即先计算括号里的子式->最后得到没有括号的式子,在调用函数计算得到结果。
值得注意的是输入运算式子时,
必须写成alogb,
必须写成pi,三角函数若不是tanN形式的话,要加上括号如tan(a+b),这是由于控制台输入的限制和为了输入后便于处理。
子函数流程:
从运算式子中读出数字和字符,分别存于一个队列中->按顺序取出数字与字符,进行乘方运算,其他的再一次放回队列中->依次再取出进行三角函数和对数的运算,其他依次放回->再依次取出进行乘除和取模运算,其他依次放回->现在只剩下加减运算,依次取出计算,得到最后的结果。
关键技术:
一、c++的sstream流的运用,可以从中分别读出运算式子的数字与字符还有去除括号时将未处理字符(即非括号的字符)以及括号的子式处理结果输出到流中,便于迭代去除括号。
二、对没括号的式子进行分级处理。
三、将式子的字符以及数字分开处理。
源代码如下:
#include
#include
#include
#include
#include
#definepi3.141592654
doublecalculate(std:
:
string);
intmain(){
//输入式子,存于s中
std:
:
strings;
std:
:
getline(std:
:
cin,s);
//抛出异常
try{
//判断是否有异常字符
conststd:
:
stringjubge="1234567890tansincos+-*/^%(|)loglnlgsqrtpi!
";
for(constauto&i:
s)
if(jubge.find(i)==-1)
throw1;////抛出异常
//将三角函数名化为数字与&字符,便于识别和计算
//以及将对数函数······
//以及阶乘·········
//以及开方·········
//将pi/π化为数字
size_tn=0;
while((n=s.find("sin"))!
=-1)
s.replace(n,3,"1&");
while((n=s.find("cos"))!
=-1)
s.replace(n,3,"2&");
while((n=s.find("tan"))!
=-1)
s.replace(n,3,"3&");
while((n=s.find("ln"))!
=-1)
s.replace(n,2,"4&");
while((n=s.find("lg"))!
=-1)
s.replace(n,2,"5&");
while((n=s.find("sqrt"))!
=-1)
s.replace(n,4,"6&");
while((n=s.find("log"))!
=-1)
s.replace(n,3,"");
while((n=s.find("!
"))!
=-1)
s.replace(n,1,"$7");
while((n=s.find("pi"))!
=-1)
s.replace(n,2,std:
:
to_string(pi));
//去除括号
while(s.find("(")!
=-1||s.find(")")!
=-1){
std:
:
ostringstreamuout;//存储未处理字符
autoleft=s.begin();//记录左括号位置
autoright=s.begin();//记录右括号位置
while(right!
=s.end()){//处理最里层括号里的字符
if(*right=='('){
if(*left=='('){
for(autoi=left;i!
=right;++i)
uout<<*i;
}
left=right;
}
elseif(*right==')'){
if(*left!
='(')throw2;////抛出异常
uout<:
string(left+1,right));
break;
}
elseif(*left!
='(')
uout<<*right;
else;
++right;
}
if(*left=='('&&right==s.end())throw3;////抛出异常
for(autoi=right+1;i!
=s.end();++i)//输出剩余未处理符
uout<<*i;
s=uout.str();//将处理一对括号后的字符串赋给s
}
//计算最后结果
doubleresult=calculate(s);
//输出结果
std:
:
cout<:
endl;
}
catch(inte){//捕获并处理异常
usingstd:
:
cout;
usingstd:
:
endl;
cout<<"InputError!
"<switch(e){
case1:
cout<<"式子中有异常字符!
"<case2:
cout<<"缺左括号!
"<case3:
cout<<"缺右括号!
"<case4:
cout<<"运算符相连或对数等复活写错!
"<default:
;
}
}
system("pause");
return0;
}
doublecalculate(std:
:
strings){
//将数字和运算符分别装入双向队列和队列适配器中
std:
:
dequenumber;
std:
:
queuesymbol;
std:
:
istringstreamuin(s);
symbol.push('+');//添加加号为第一个运算符
doubletpn;chartpc;
while(uin>>tpn>>tpc)
number.push_back(tpn),symbol.push(tpc);
if(!
uin.eof())throw4;////抛出异常
number.push_back(tpn);//添加最后一个数字
//计算乘方
for(inti=0,n=number.size();itpc=symbol.front();symbol.pop();//取出运算符
tpn=number.front();number.pop_front();//取出数字
if(tpc=='^'){//计算乘方
doubletemp=number.back();
number.back()=pow(temp,tpn);
}
else{
symbol.push(tpc);//放回队列,置于最后
number.push_back(tpn);//放回队列,置于最后
}
}
//计算三角函数以及对数
for(inti=0,n=number.size();itpc=symbol.front();symbol.pop();//取出运算符
tpn=number.front();number.pop_front();//取出数字
if(tpc=='&'){//计算乘方以及对数
switch(int(number.back())){
case1:
number.back()=sin(tpn);break;
case2:
number.back()=cos(tpn);break;
case3:
number.back()=tan(tpn);break;
case4:
number.back()=log(tpn);break;
case5:
number.back()=log10(tpn);break;
case6:
number.back()=sqrt(tpn);break;
default:
;
}
}
elseif(tpc==''){//计算对数
doubletemp=number.back();
number.back()=log(tpn)/log(temp);
}
elseif(tpc=='$'){//计算阶乘
intn=number.back();
number.back()=1;
for(inti=1;i<=n;++i)
number.back()*=i;
}
else{
symbol.push(tpc);//放回队列,置于最后
number.push_back(tpn);//放回队列,置于最后
}
}
//计算乘除以及取模运算
for(inti=0,n=number.size();itpc=symbol.front();symbol.pop();//取出运算符
tpn=number.front();number.pop_front();//取出数字
if(tpc=='+'||tpc=='-'){
symbol.push(tpc);
number.push_back(tpn);
}
elseif(tpc=='*')
number.back()*=tpn;//计算乘
elseif(tpc=='/')
number.back()/=tpn;//计算除
else{//取模运算
doubletemp=number.back();
temp=int(temp)%int(tpn);
number.back()=temp;
}
}
//计算加减得出结果
doubleresult=0;
for(inti=0,n=number.size();itpc=symbol.front();symbol.pop();
tpn=number.front();number.pop_front();
if(tpc=='+')//+
result+=tpn;
else//-
result-=tpn;
}
returnresult;
}