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

📄 表达式.cpp

📁 这是一个表达试求值的代码,主要用堆栈来实现.考查我们的数据结构知识.
💻 CPP
字号:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<malloc.h>
#define max 100
//********************************************************
double   tran_num(char c[],int *i);                //把数字字符转化成浮点型数字
void    postfix_ex(char a[],char opr[]);          //求后缀表达式
int     grade(char c);                            //返回运算符号的优先等级
int     find(char x[],char y);                    //数组元素查找
float   count(char a[]);                          //求后缀表达式的值
float   div(float x,float y);                     //除法
float   sqr(float x);                             //开方 
float   power(float x,float y);                   //乘方
float   fac(float x);                             //阶乘 
float   arrange(float x,float n);                 //排列
float   combin(float x,float n);                  //组合
int     match_chara(char b[]);                    //括号匹配 
int     il_chara(char b[]);                       //检查非法字符
//******************************************************** 
struct  stack
{
   int top;
   char a[max];
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%栈的操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void  InitStack(struct stack *t)               //初始化栈
{
	t->top=-1;
}
void   pop(struct stack *t)              //元素出栈
{
	if(-1 < t->top && t->top < max)
		t->top--;
}   
void push( struct stack *t,char x)        //元素进栈
{
	if(-1<=t->top && t->top<max-1)
	{
		t->top++;
	    t->a[t->top]=x;
	}
}
char  gettop( struct stack *t)            //取栈顶元素
{
	if(-1<t->top&&t->top<max)
		return(t->a[t->top]);
	else
		return(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%工具函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float  div(float  x,float  y)                     //除法运算
{    
	 if(y==0)
	 {	
		 printf("除数不能为0\n");
	 }	
     else
		 return (x/y);
}  
float sqr(float  x)                         //开平方运算
{
   if(x<0)
	   printf("被开方数不能小于零\n");
   else
	   return ( (float)sqrt(x) );
}
float power(float  x,float y)                //乘方运算
{    
	 int i;
	 float sum=1.00000;
     if(x==0)
		 printf("乘方的底数不为零\n");
	 else if(y>0)
	 {
	    for(i=1;i<=y;i++)
			sum=sum*x;
	     return(sum);
	 }
      else if(y==0.0)
      return(sum);
	  else	  
	  {for(i=1;i<=y;i++)
			sum=sum*x;
	     return( (float)1.0/sum);
	  }
}
float  fac(float  x)            //阶乘运算
{
     int i;
	 float  sum=1.0;
	 if(x==0)
		 return(sum);
	  if(x>0)	 
	  {
		  for(i=1;i<=x;i++)
			 sum=sum*i;
		 return(sum);
	  }
	 if(x<0) 
		 printf("阶乘的的基数不为负数\n");
}
float  arrange(float  x,float  n)       //排列运算
{    
	float  i;
    float  sum=1.0;
     if(x>n)
		 printf("排列的上指数不能大于下指数\n");
	 else if(x==n)
		 return( fac(x));
	 else  
		 for(i=n+1-x;i<=n;i++)
			 sum=i*sum;
		 return(sum);
}
float  combin(float  x,float  n)            //组合运算
{    
	float 	 sum;
     if(x>n)
		 printf("排列的上指数不能大于下指数\n");
        else if(x==n)
			return(1.0);
		else
			sum=arrange(x,n)/fac(x);
              return(sum);           
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%运算符优先级判定函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int   grade(char c)
{   
    if(c=='#')
      return(-1);
    if(c=='(')
      return(0);
    if(c=='+'||c=='-')
		return(1);
	if(c=='*'||c=='/')
        return(2);
	if(c=='!'||c=='^'||c=='A'||c=='a'||c=='S'||c=='s'||c=='C'||c=='c')
        return(3);
} 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int   il_chara(char b[])             //检查表达式子中是否有非法字出现
{
       	char s[22]={"()[]{}!^ACSacs+-/*.,"}; 
        int  i=0,k=-1,j;                   //k的值用来标志表达式中的字符是否和数组s中的元素相等
            while(b[i]!='\0')
			{
				if('9'<b[i]||b[i]<'0')
				{ 
                  for(j=0;j<22;j++)				  
					  if(b[i]!=s[j])
					  continue;
					  else k=j;
					  if(k==-1)            //如果k的数值还是为初始值,那么就有非法字出现
						 {					    
						    printf("表达式中有非法字符出现\n");
							return(0);
					        break;
						 }
						 else
							 return(1);
				 }
				 i++;
				 k=-1;
			}
}
int   match_chara(char b[])        //检查表达式子中的括号是否配对 
{      
	int i=0,j=0;              
	struct stack *s;
	s=(struct stack *) malloc(sizeof(struct stack));
        InitStack(s);
		while(b[i]!='\0')
		{ 
		   switch(b[i])                         
			 {
	           case'(':push(s,b[i]);       //遇到左括号进栈 
				   break;
               case'[':push(s,b[i]);
				       b[i]='(';
				      break;
               case'{':push(s,b[i]);
				   b[i]='(';
				      break;
			   case')':if(gettop(s)=='(') pop(s);      //遇到右括号出栈
				      else 
					  {
					        printf("括号不匹配\n");
					        return(0);
					  }
					  break;
               case']':
				      if(gettop(s)=='[') pop(s);      
					  else
					  {
						  printf("括号不匹配\n");    
					      b[i]=')';                  // 并把相应的大中括号改成小括号
						  return(0);
				         break;
					  }
               case'}':
				      if(gettop(s)=='{') pop(s); 
				      else 
					  {
						  printf("括号不匹配\n");
					      b[i]=')';
						  return(0);
				          break;
					  }
			 }		 
				i++; 	
		}
		if(s->top!=-1)                               //如果栈为空说明括号匹配否则不匹配
		{
			printf("数学表达式括号不匹配\n");
			return(0);
		}
		else
			return(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double  tran_num(char c[],int *i)                  //将数字的字符串转化为实数
{
       int k=0,j=0;                               
	   double sum1=0.0,sum2=0.0;                    
	   while(c[*i]>='0'&&c[*i]<='9'||c[*i]=='.')
	  {
		  if('0'<=c[*i]&&c[*i]<='9')
		  {
		       sum1=sum1*10.0+(c[*i]-48);            //sum1纪录整数部分
			   (*i)++;
		   }
		  else
		  {   
			  (*i)++;
			  while('0'<=c[*i]&&c[*i]<='9')
			  {
			  	  k++;                               //k用来纪录小数的位数
			      sum2=sum2*10+(c[*i]-48);
			      (*i)++;
			  }		  
			  while(j<k)                            //sum2纪录小数部分
			  {
			      sum2=sum2/10.0;
				  j++;
			   }
		  }		 
	  }
     return (sum1+sum2);
}
 int   find(char x[],char y)                      //查找数组x中是否存在y
 {
         int i=0;
		 while(x[i]!='\0')
		 {
		   if(x[i]==y)
			   return(1);
		   else
			   i++;	 
		 }
 }
//&&&&&&&&&&&&&&&&&&&&&&求后缀表达式函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 void    postfix_ex(char a[],char opr[])                                
 {	 
       int i=0,top=0;                                     
	   char x[]={"+*-/aAcCSs!^"};         //数组x中存所有可能出现的运算符         
	   struct stack *s;
      s=(struct stack *) malloc(sizeof(struct stack));
        InitStack(s);
	     push(s,'#');                                 //用#标志运算完成
	   while(a[i]!='\0')
	   {
	      if((a[i]>='0'&&a[i]<='9')||a[i]=='.') 
		  {
			  opr[top]=a[i];
		        top++;
		  }	   
		  else if(find(x,a[i])==1||a[i]==',')       //当遇到运算符号或逗号 就空格赋给后缀数组
		  {   
			  opr[top]=' ';
			  top++;
			  if(find(x,a[i])==1)
			  {  
				 if(grade(a[i])>grade(s->a[s->top])) //当表达式中运算符等级高于栈顶元素
				 push(s,a[i]);                       //运算符进栈
			      else 
				{
				   while(grade(a[i])<=grade(s->a[s->top]))  //当表达式中运算符等级不高于栈顶元素
				   {
				    opr[top]=gettop(s);                     //栈顶运算符进后缀数组
				     top++;
			        pop(s);
				   } 	
                   push(s,a[i]);                            //把原表达式中的运算符进栈
				 }
			  }
		  }
		        else if(a[i]=='(')
				    push(s,'(');
			         else if(a[i]==')')                 //当遇到右括号时,把和该右括号
					 {
					   while(s->a[s->top]!='(')       //配对的左括号之间的运算号出栈且赋给后缀数组
					   {
					     opr[top]=gettop(s); 
						 top++;
						  pop(s);
					   }
					  pop(s);                             //把左括号也出栈
					}
					i++;   
	   }        
	      while((s->top)!=0)                 //当运算符栈不为空时
		  {
			  opr[top]=gettop(s);            //依次把栈里的运算符放进后缀数组
			  top++;
		      pop(s);
		  }
			  opr[top]='\0';               //给缀数组加上结束符以便以字符串输出          
}
//%—%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float count(char a[])
 {
       int i=0,top=-1;
	   float x,op[50];
	   while(a[i]!='\0')
	   {
	      if(a[i]>='0'&&a[i]<='9')
		  {   
			  ++top;
			  op[top]=(float)tran_num(a,&i);                    //把数字字符串转化成实数
		  }
				        else if(a[i]=='+')
						{
				           x=op[top];
                           top--;
				           op[top]=x+op[top];
						   i++;
						}
				        else if(a[i]=='-')
						{
					       x=op[top];
					       top--;
					       op[top]=op[top]-x;
						   i++;
						}
				        else if(a[i]=='*')
						{
						     x=op[top];
							 top--;
							 op[top]=x*op[top];
							 i++;
						}
					    else if(a[i]=='/')
						{
						     x=op[top];
							 top--;
							 op[top]=div(op[top],x);
							 i++;
						}
						else if(a[i]=='!')
						{
						     x=op[top];
						    op[top]=fac(x);
							i++;
						}
						else if(a[i]=='s'||a[i]=='S')
						{
						      x=op[top];
							  op[top]=sqr(x);
							  i++;
						}
						else if(a[i]=='^')
						{
							x=op[top];
							top--;
							op[top]=power(op[top],x);
							i++;
						}
						else if(a[i]=='a'||a[i]=='A')
						{
						     x=op[top];
						     top--;
							 op[top]=arrange(x,op[top]);
							 i++;
						}
						else if(a[i]=='c'||a[i]=='C')
						{
						     x=op[top];
							 top--;
							 op[top]=combin(x,op[top]);
							 i++;
						} 
						else i++;
	   }
	   return(op[top]);  
 }
int  main(void)
{   
     float y;
	 int p,q;  
	 char  b[max];
	 char  e[max];//{"35.5+a((a(3,2)+2),2)+(c(3,1))!-c(5,4)*2+(5^(c(3,1)))/1.25"};
	 printf("***************************************************************\n");
	 printf("*                制作时间:2006年12月                         *\n");
	 printf("*               制作人:廖过房,2004051686                     *\n");
	 printf("*  欢迎使用此系统,此系统能完成简单的表达式的求值计算.       *\n");
	 printf("***************************************************************\n");
	 printf("为了能正确用此系统,请使用前阅读输入格式:\n");
	 printf("##############################################################\n");
     printf("#   开方:s(a)----乘方:a^n----阶乘:a!                      #\n");
	 printf("#   排列a(m,n)  其中n<=m----组合c(m,n)  其中 n<=m         #\n");    
	 printf("##############################################################\n");
l:   printf("注意:请输入表达式后按回车以示结束,表达式不要有空格,结束时不用加"=",\n");
	 printf("请输入表达式(若要退出请输入EXIT):");
	 scanf("%s",e);
	 while(strcmp(e,"EXIT")!=0) 
	 {
     printf("原表达式:%s\n",e);
     p=il_chara(e);                         //p的值是1说明没有非法字符
	 q=match_chara(e);                      //q的值是1说明括号匹配
	 if(p==1&&q==1)             
	 {
        postfix_ex(e,b);
        printf("后缀表达式:%s\n",b);
        y=count(b);
	    printf("表达式的值:%f\n",y);
	 }
	else
	{
		printf("请重新输入:\n");
		goto l;
	}
     printf("\n\n请输入表达式(若要退出请输入EXIT):");
     scanf("%s",e);
	 }
	 printf("谢谢使用本系统,你已经成功退出!\n");
	 return 0;
	}
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -