⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 四则运算.cpp

📁 实现了四则运算的加法与乘法
💻 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 + -