支持的运算符有+、-、*、/、^、sin()、cos()、log()、ln()。
支持的操作数为正数(暂未实现负数和小数)。
以前在王道论坛上做过实现+、-、*、/的运算,现在多了几个三角函数运算。
尝试着做了一下,暂看不出哪里有错误,哪位大神看出来了请指点一下哈!
▶▶▶小知识点:在vs2005以及之后的版本中,推荐用scanf_s、printf_s、gets_s代替scanf、printf、gets。
▶▶▶理由:scanf()等在读取时不检查边界,所以可能会造成内存泄露。所以vc++2005/2008中提供了scanf_s()等函数,在最新的VS2013中也提供了scanf_s()。在调用时,必须提供一个数字以表明最多读取多少位字符。
#include <cstdio>
#include <stack>
#include <math.h>
using namespace std;
// + 1
// - 2
// * 3
// / 4
// ^ 5
// sin() 6
// cos() 7
// log() 8
// ln() 9
// ( 10
// ) 11
char str[220];
//mat[i][j]==1表示i的优先级比j的优先级大
int mat[12][12]={
1,0,0,0,0,0,0,0,0,0,1,0,
1,0,0,0,0,0,0,0,0,0,1,0,
1,0,0,0,0,0,0,0,0,0,1,0,
1,1,1,0,0,0,0,0,0,0,1,0,
1,1,1,0,0,0,0,0,0,0,1,0,
1,1,1,1,1,0,0,0,0,0,1,0,
1,1,1,1,1,0,0,0,0,0,1,0,
1,1,1,1,1,0,0,0,0,0,1,0,
1,1,1,1,1,0,0,0,0,0,1,0,
1,1,1,1,1,0,0,0,0,0,1,0,
1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,1,0,
};
stack<double> in; //数字栈
stack<int> op; //运算符
void getOp(bool &reto,int &retn,int &i){
if(i==0&&op.empty()){
reto=true;
retn=0;
return;
}
if(str[i]==0){
reto=true;
retn=0;
return;
}
if(str[i]<='9'&&str[i]>='0'){
reto=false;
}
else{
reto=true;
switch(str[i]){
case '+':
retn=1;
i+=1;
break;
case '-':
retn=2;
i+=1;
break;
case '*':
retn=3;
i+=1;
break;
case '/':
retn=4;
i+=1;
break;
case '^':
retn=5;
i+=1;
break;
case 's':
retn=6;
i+=3;
break;
case 'c':
retn=7;
i+=3;
break;
case 'l':
if(str[i+1]=='o'){
retn=8;
i+=3;
}
else {
retn=9;
i+=2;
}
break;
case '(':
retn=10;
i+=1;
break;
case ')':
retn=11;
i+=1;
break;
default:
break;
}
return;
}
retn=0;
for(;str[i]<='9'&&str[i]>='0';i++){
retn*=10;
retn+=str[i]-'0';
}
return ;
}
int main(){
printf_s("本程序为简易计算。\n.支持的运算符有:+、-、*、/、^、sin()、cos()、log()、ln()。\n");
printf_s("支持的操作数为整数;公式中不含有空格;\n");
while(gets_s(str)){
if(str[0]=='0'&&str[1]=='0')break;
bool retop; int retnum;
int idx=0;
while(!op.empty())op.pop();
while(!in.empty())in.pop();
while(true){
getOp(retop,retnum,idx);
if(retop==false){
in.push((double)retnum);
}
else{
double a,b;
if(op.empty()==true||(retnum!=11&&mat[retnum][op.top()]==1)){
op.push(retnum);
}
else{
while(mat[retnum][op.top()]==0){
int ret=op.top();
op.pop();
if(ret<=5||ret==8){
b=in.top();in.pop();
a=in.top();in.pop();
if(ret==1)
a=a+b;
else if(ret==2)
a=a-b;
else if(ret==3)a=a*b;
else if(ret==4)a=a/b;
else if(ret==5)a=pow(a,b);
else if(ret==8)a=log(b)/log(a);
}
else{
a=in.top();in.pop();
if(ret==6)a=sin(a);
else if(ret==7)a=cos(a);
else if(ret==9)a=log(a);
}
in.push(a);
}
if(retnum!=11)op.push(retnum);
else op.pop();
}
}
if(op.size()==2&&op.top()==0)break;
}
printf_s("%.3f\n",in.top());
}
return 0;
}