📄 四则运算.cpp
字号:
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
const int STACK_INIT_SIZE=100;
const int STACKINCREMENT=10;
const char OP[7]={'+','-','*','/','(',')','='};
typedef struct
{
double *base;
double *top;
int stacksize;
}SqStack;
void InitStack(SqStack &);
void Push(SqStack &,double);
int In(char);
double ChangeChar(char aaa[], int i); //字符转换数字
double GetTop(SqStack &);
char Precede(double,double);
double Pop(SqStack &);
double Operate(double,double,double);
int main()
{
char c; double cc; //用c提取输入的字符放入aa数组,用cc提取bb数组中的算符值,数值
double x=0.0;
double sign=0.0; //sign作为+-×/符号代码
double a ,b;
cout<<"说明:"<<endl;
cout<<"1.前一算式正确,可进行新算式。"<<endl;
cout<<"2.当要结束时,输入一个非正常字符。如#"<<endl;
cout<<endl;
cout<<"请输入算式,以“=”结尾:"<<endl; //a,b 为待运算数
ComeOn:
char aa[50][40]={{'\0'},{'\0'}}; //aa数组存符号,算符和数字符
double bb[50]={0.0}; //bb数组存符号的转换数值
SqStack OPTR; //定义算符栈
InitStack(OPTR);
Push(OPTR,9e-30);
SqStack OPND; //定义数值栈
InitStack(OPND);
c=getchar(); //取得当前字符
int i=0;
int j=0;
while(c!='\n')
{ if((c<'0'||c>'9')&&In(c)==0){cout<<"非正常字符输入,结束。"<<endl;return 0;}
while(In(c)) //算符进入字符数组,只存在于aa[i][0]
{
aa[i][0]=c;
c=getchar();
i++; //换行存储
}
j=0; //一组算符存好后存数字符
while(c>='0'&&c<='9'||c=='.') //数字符及小数点进入字符数组,占据aa[i][j]
{
aa[i][j]=c;
j++; //在 当前行 换列存储
c=getchar();
}
i++; //一组数字符存好后继续存算符
}
for (i=0;i<=49&&aa[i][0]!='\0';i++)
{
for(j=0;j<=4;j++) //第一个算符为“+-×/(=”,第二个算符为“+-×/)=”,中间无数字要报错
{
for(int k=0;k<=3;k++)
{
if((aa[i][0]==OP[j]||aa[i][0]==OP[6])&&(aa[i+1][0]==OP[k]||aa[i+1][0]==OP[5]||aa[i+1][0]==OP[6]))
{cout<<"运算符输入出错!!!"<<endl;return 0;}
}
}
if(aa[i][0]>='0'&&aa[i][0]<='9') //对数字字符的转换
{
bb[i]=ChangeChar(aa[i],i);
}
if(In(aa[i][0])) //对算符字符的转换
{
switch(aa[i][0])
{
case '+': bb[i]=1e-30;break; //用一个极小的数值来代替算符
case '-': bb[i]=2e-30;break;
case '*': bb[i]=4e-30;break;
case '/': bb[i]=5e-30;break;
case '(': bb[i]=7e-30;break;
case ')': bb[i]=8e-30;break;
case '=': bb[i]=9e-30;break;
}
}
}
cc=bb[0]; j=0;
while(int(cc*1e30)!=9||int(GetTop(OPTR)*1e30)!=9) //栈的核心应用
{
if(fabs(cc)>1e-20){Push(OPND,cc);j++;cc=bb[j];}
else
switch(Precede(GetTop(OPTR),cc)) //运算优先级的比较
{
case '<':Push(OPTR,cc);j++;cc=bb[j];break;
case '=':x=Pop(OPTR);j++;cc=bb[j];break;
case '>':sign=Pop(OPTR); b=Pop(OPND);a=Pop(OPND);
Push(OPND,Operate(a,sign,b));break;
}
}
double m=0.0;
m=GetTop(OPND);
cout<<"运算结果:"<<setprecision(20)<<m<<endl;
cout<<endl;
goto ComeOn;
return 0;
}
void InitStack(SqStack &S) //栈的初始化
{
S.base=(double *)malloc(STACK_INIT_SIZE*sizeof(double));
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
void Push(SqStack &S,double aa) //入栈
{
if((S.top-S.base)>=S.stacksize)
{
S.base=(double *)realloc(S.base,(S.stacksize+STACKINCREMENT) * sizeof(double));
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=aa;
}
int In(char c) //判断是否为运算符,是返回1,否返回0
{
int i,j;
for(i=0;i<=6;i++)
{
if(c==OP[i]) {j=1;break;}
else j=0;
}
return j;
}
double ChangeChar(char aaa[],int i) //把数字字符转换为数值
{
int j,k,l,p;
double n=0.0,m=0.0;
for(j=0;j<=39;j++) //对小数点进行定位,无小数点返回-1
{
if(aaa[j]=='.') {k=j-1; break;}
else k=-1;
}
for(j=0;j<=39;j++) //对最末位定位
{
if(aaa[j]=='\0') {l=j-1;break;}
}
if(k==-1) //整数情况转数值
{
for(p=0;p<=l;p++)
{
m=(aaa[p]-'0')*pow(10,l-p);
n=n+m;
}
}
else //小数情况转数值
{
for(p=0;p<=k;p++) //小数的整数部分
{
m=(aaa[p]-'0')*pow(10,k-p);
n=n+m;
}
for(p=k+2;p<=l;p++) //小数的小数部分
{
m=(aaa[p]-'0')*pow(10,k-p+1);
n=n+m;
}
}
return n;
}
double GetTop(SqStack &S) //取得栈顶元素
{
double aa=0.0;
if((S.top-S.base)!=0)
aa=*(S.top-1);
return aa;
}
char Precede(double a,double b) //优先级的比较
{
char f;
int i,j;
int aa,bb;
aa=int(1e30*a);
bb=int(1e30*b);
switch(aa) //前一个算符
{
case 1: i=20; break; //用数字代替其优先权+-×/()=
case 2: i=20; break;
case 4: i=40; break;
case 5: i=40; break;
case 7: i=0; break;
case 8: i=50; break;
case 9: i=-10; break;
}
switch(bb) //当前算符
{
case 1: j=10; break; //用数字代替其优先权+-×/()=
case 2: j=10; break;
case 4: j=30; break;
case 5: j=30; break;
case 7: j=50; break;
case 8: j= 0; break;
case 9: j=-10; break;
}
if(i>j) f='>';
if(i==j) f='=';
if(i<j) f='<';
return f;
}
double Pop(SqStack &S) //出栈
{
double aa=0.0;
if((S.top-S.base)!=0)
aa=*--S.top;
return aa;
}
double Operate(double a,double sign,double b) //具体两数运算
{
double m=0.0;
int ssign;
ssign=int(sign*1e30); //对算符数值的转换,准备switch,case
switch(ssign)
{
case 1: m=a+b; break;
case 2: m=a-b; break;
case 4: m=a*b; break;
case 5: m=a/b; break;
}
return m;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -