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

📄 表达式求值.cpp

📁 同Windows自带的计算器类似的程序
💻 CPP
字号:
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#include<math.h>
#include<malloc.h>
#include<stdlib.h>
#include<iostream.h>
#include<string.h>

#define prompt printf("Pb4801039>")

const max=300;
const stackinitsize=300;
const stackincrement=100;

double trans=1;

typedef struct
{char *elem;
 int top;
 int stacksize;
 int increment;
}stack_C;

typedef struct
{double *elem;
 int top;
 int stacksize;
 int increment;
}stack_F;

typedef struct lnode
{float data;
 char oper;
 struct lnode *next;
}lnode,*linklist;


int Error(char *s)
{printf("\n       %s\n",s);
 printf("\n");
 return 0;
}
void initstack_C(stack_C &S,int maxsize=stackinitsize,int incresize=stackincrement)
{ S.elem=new char[maxsize];
  S.top=-1;
  S.stacksize=maxsize;
  S.increment=incresize;}

void initstack_F(stack_F &S,int maxsize=stackinitsize,int incresize=stackincrement)
{ S.elem=new double[maxsize];
  S.top=-1;
  S.stacksize=maxsize;
  S.increment=incresize;}

char gettop_C(stack_C S,char &e)
{if(S.top==-1) return '\0';                      // Error("栈已空")
 e=S.elem[S.top];
 return e;}

void push_C(stack_C &S,char e)
{if(S.top==S.stacksize-1)
{         int newsize=S.stacksize+S.increment;
          char *newbase=new char[newsize];
		  for(int i=0;i<S.stacksize;i++)
			  newbase[i]=S.elem[i];
		  delete S.elem;
          S.elem=newbase;
          S.stacksize+=S.increment;
}

S.elem[++S.top]=e;
}


void push_F(stack_F &S,double e)
{if(S.top==S.stacksize-1)
{         int newsize=S.stacksize+S.increment;
          double *newbase=(double *)realloc(S.elem,newsize*sizeof(double));
          S.elem=newbase;
          S.stacksize+=S.increment;}

S.elem[++S.top]=e;
}

void pop_C(stack_C &S,char &e)
{   if(S.top==-1)  Error("栈已空!");
    e=S.elem[S.top--];
}

void pop_F(stack_F &S,double &e)
{   if(S.top==-1)  Error("栈已空!");
    e=S.elem[S.top--];
}

int stackempty_C(stack_C S)
{if(S.top==-1) return 1;
 else return 0;
}

int stackempty_F(stack_F S)
{if(S.top==-1) return 1;
 else return 0;
}

void info()
{system("title   小型表达式求值系统");system("color 0b");
 printf("\n\n请输入表达式,可以使用函数和括号。\n\n");
 printf("比如sin,cos,tan,sinh,cosh,tanh,ln,lg,exp,!,%%%等数学函数。  \n\n");
 //printf("三角函数默认使用的是弧度制,但可以用declare deg/rad改变。\n");
 //printf("还可以使用大中小括号({[()]}),但需注意优先级不要搞错。  \n");
 printf("需要帮助请输入help, 若退出可以输入exit, 也可以直接回车。  \n\n");
 printf("--------------------------欢迎使用---------------------------\n\n");
}

void help()
{printf("\n\n请输入表达式,可以使用函数,\n");
 printf("比如sin,cos,tan,sinh,cosh,tanh,ln,lg,exp,!,%%%等函数。  \n");
 printf("三角函数默认使用的是弧度制,但可以用declare命令改变。\n");
 printf("格式为declare deg/rad;可以使用show命令察看当前设置。\n");
 printf("还可以使用大中小括号({[()]}),但需注意优先级不要搞错。  \n");
 printf("可以使用的命令有time,date,exit,cls,color xx 等。  \n");
 printf("--------------------------欢迎使用---------------------------\n\n");
}

int fac(int n)
{int result=1;
 if(n==0)  return 1;
 while(n>0)  result*=n--;
 return result;
}

int get(char exp[])
{int flag=1,i=0;char ch='c';
  scanf("%c",&ch);
  while(ch!='\n')
  {    if(flag&&(ch=='-'||ch=='+')) exp[i++]='0';
	   else flag=0;
       exp[i++]=ch;
       if(ch=='(') flag=1;
	   scanf("%c",&ch);
  }
  exp[i]='\0';
  if(!strcmp(exp,"help"))            {help();return 0;}
  else if(!strcmp(exp,"exit"))       exit(0);
  else if(!strcmp(exp,"time"))       {system("time /t");return 0;}
  else if(!strcmp(exp,"date"))       {system("date /t");return 0;}
  else if(!strcmp(exp,"cls"))        {system("cls");printf("\n");return 0;}
  else if(strstr(exp,"color"))       {system(exp);return 0;}
  else if(!strcmp(exp,"declare deg")) {trans=3.14159265/180;printf("已改为角度制。\n");return 0;}
  else if(!strcmp(exp,"declare rad")) {trans=1;printf("已改为弧度制。\n");return 0;}
  else if(!strcmp(exp,"show"))        {if(trans==1) printf("现在为弧度制。\n");else printf("现在为角度制。\n");return 0;}
  else  {exp[i]='#';exp[i+1]='\0';return 1;}
  
}



int  functionprocess(char exp[])
{char *ch=exp;char temp[200];char *pch;char *q=temp;int k=0;
while(*ch!='#')
{ if(!strchr("+-*/()^!%1234567890.",*ch))
  switch(*ch)
{      case 's' :   {q=temp;while((*ch=='i'||*ch=='h'||*ch=='n'||*ch=='s')&&++k<=3)
                    *q++=*ch++;if(*ch=='h') {*q='h';ch++;q++;}*q='\0';
                   if(strcmp(temp,"sin")==0)
					{    *(ch-2)=*(ch-3)=' ';*(ch-1)='s';  }
				   else if(strcmp(temp,"sinh")==0)
					{    *(ch-2)=*(ch-3)=*(ch-4)=' ';*(ch-1)='S';}
			    else return Error("Ilegal char!");k=0;break;}
       case 'c' :   {q=temp;while((*ch=='o'||*ch=='h'||*ch=='s'||*ch=='c')&&++k<=3)
		            *q++=*ch++;if(*ch=='h') {*q='h';ch++;q++;}*q='\0';
                    if(strcmp(temp,"cos")==0)
					{    *(ch-2)=*(ch-3)=' ';*(ch-1)='c';}
                    else if(strcmp(temp,"cosh")==0)
					{    *(ch-2)=*(ch-3)=*(ch-4)=' ';*(ch-1)='C';}
				else return Error("Ilegal char!");k=0;break;}
	  case 't' :   {q=temp;while((*ch=='a'||*ch=='n'||*ch=='h'||*ch=='t')&&++k<=3)
		            *q++=*ch++;if(*ch=='h') {*q='h';ch++;q++;}*q='\0';
                    if(strcmp(temp,"tan")==0)
					{    *(ch-2)=*(ch-3)=' ';*(ch-1)='t';}
                    else if(strcmp(temp,"tanh")==0)
					{   *(ch-2)=*(ch-3)=*(ch-4)=' ';*(ch-1)='T';}
				else return Error("Ilegal char!");k=0;break;}
	  case 'l' :   {q=temp;while((*ch=='g'||*ch=='n'||*ch=='l')&&++k<=2)
		            *q++=*ch++;*q='\0';
                    if(strcmp(temp,"lg")==0)
					{   *(ch-2)=' ';*(ch-1)='l';}
                    else if(strcmp(temp,"ln")==0)
					{    *(ch-2)=' ';*(ch-1)='L';}
				else return Error("Ilegal char!");k=0;break;}
     case 'e'  :   {q=temp;while((*ch=='x'||*ch=='p'||*ch=='e')&&++k<=3)
		            *q++=*ch++;*q='\0';
                    if(strcmp(temp,"exp")==0)
					{    *(ch-2)=*(ch-3)=' ';*(ch-1)='e';}
                   	else Error("Ilegal char!");k=0;break;}
	 default  :   return Error("存在非法字符!");}  //end switch
     if((*ch<'a')||(*ch>'z')) 
	     ch++;
 } //end while
 if(strchr(exp,' ')) {
 ch=exp;pch=temp;
 while(*ch!='\0')
 {  if(*ch!=' ') *pch++=*ch++;
    else ch++;}
 *pch='\0';
 strcpy(exp,temp);}
 return 1;
} // end functionprocess

int  match(char *exp)
{int flag1=0,flag2=0;char *temp=exp;char ch=*temp++,e;stack_C S;initstack_C(S);
 while(ch!='#')
 switch(ch)
 {        case '{' : push_C(S,ch);flag1=1;flag2=1;*(temp-1)='(';ch=*temp++;break;
          case '[' : push_C(S,ch);flag1=0;flag2=1;*(temp-1)='(';ch=*temp++;break;
          case '(' : push_C(S,ch);flag1=0;flag2=0;ch=*temp++;break;
		  case ')' : {if(stackempty_C(S)) return Error("有多余括号!");
			          else if(gettop_C(S,e)=='(') {pop_C(S,e);ch=*temp++;}
					  else return Error("括号不匹配!");break;}
		  case ']' : {if(stackempty_C(S))return  Error("有多余括号");
                      else if(gettop_C(S,e)!='[') return Error("括号不匹配!");
					  else if(flag2) return Error("优先级错误!");
					  else {pop_C(S,e);*(temp-1)=')';ch=*temp++;}break;}
		  case '}' : {if(stackempty_C(S)) return Error("有多余括号");
			          else if(gettop_C(S,e)!='{') return Error("括号不匹配!");
					  else if((flag1)&&(flag2)) return  Error("优先级错误!");
                      else {pop_C(S,e);*(temp-1)=')';ch=*temp++;}break;}
		  default  :  ch=*temp++;}
 if(!stackempty_C(S)) return Error("有多余括号!");
 return 1;
}


int precede(char c,char ch)
{char oper[]="#(+-+/*/^";char func[]="%!sctSCTLle";
 char *p,*ph;
 ph=strchr(oper,ch);
 if(ph)    p=strchr(ph,c);
 if(strchr(func,c)&&strchr(func,ch))   return 0;
 else if(strchr(func,c))               return 1;
 else if(strchr(func,ch))              return 0;
 else if(p>=ph)                        return 1;
 else                                  return 0;
}

void change(char *p,int &n,float &num)
{char data[20];char *q=data; n=0;
 while((*p<='9'&&*p>='0')||(*p=='.'))
 {      *q++=*p++;n++;}
 *q='\0';
 num=(float)atof(data);}
void insert(linklist &head,linklist &p,float e,char c='\0')
{linklist q=new lnode;
 q->data=e;
 q->oper=c;
 q->next=NULL;
 p->next=q;
 p=q;}

int transform(linklist &suffix,char *exp)
{ int k=0;linklist p=suffix;char c;int n;float num;stack_C S;
 initstack_C(S);push_C(S,'#');
 while(!stackempty_C(S))
 {    if(strchr("+-*/^()sScCtTeLl%!#",*exp)==0)
 {           change(exp,n,num);
             exp+=(n-1);
             insert(suffix,p,num);}
      else if(*exp=='(')      push_C(S,*exp);
	  else if(*exp==')')
	  {       pop_C(S,c);
	          while(c!='(')   
			  {      insert(suffix,p,0,c);pop_C(S,c);}
	  }
	  else   {while(gettop_C(S,c)&&(precede(c,*exp)))
	  {             insert(suffix,p,0,c);pop_C(S,c);}
	  if(*exp!='#')     push_C(S,*exp);}
 exp++;}
 return 1;
}



int value(stack_F &S,char ch)
{double a,b;
 switch(ch)
 {case '+' : pop_F(S,a);pop_F(S,b);push_F(S,a+b);break;
  case '-' : pop_F(S,a);pop_F(S,b);push_F(S,b-a);break;
  case '*' : pop_F(S,a);pop_F(S,b);push_F(S,a*b);break;
  case '/' : pop_F(S,a);pop_F(S,b);if(!b) Error("div zero");push_F(S,b/a);break;
  case '^' : pop_F(S,a);pop_F(S,b);push_F(S,pow(b,a));break;
  case 'S' : pop_F(S,a);push_F(S,sinh(a));break;
  case 's' : pop_F(S,a);push_F(S,sin(a*trans));break;
  case 'c' : pop_F(S,a);push_F(S,cos(a*trans));break;
  case 'C' : pop_F(S,a);push_F(S,cosh(a));break;
  case 'e' : pop_F(S,a);push_F(S,exp(a));break;
  case 'L' : pop_F(S,a);if(a<=0) Error("Log erro!");push_F(S,log(a));break;
  case 'l' : pop_F(S,a);if(a<=0) Error("Log error!");push_F(S,log10(a));break;
  case 't' : pop_F(S,a);push_F(S,tan(a*trans));break;
  case 'T' : pop_F(S,a);push_F(S,tanh(a));break;
  case '%' : pop_F(S,a);pop_F(S,b);push_F(S,fmod(b,a));break;
  case '!' : pop_F(S,a);push_F(S,fac((int)a));break;
  default  : return Error("Invaid oper!");
 }
}


double calc(linklist suffix)
{stack_F S; linklist p=suffix->next;double result;
 initstack_F(S);
 while(p&&p->oper!='#')
 {     if(!p->oper)   push_F(S,p->data);
       else           value(S,p->oper);
	   p=p->next;}
 pop_F(S,result);
 return result;
}

void main()
{double result;
 char exp[90],temp[90];
 linklist suffix=new lnode;
 suffix->next=NULL;
 info();
 loof:prompt;
      if (get(exp)){
	     strcpy(temp,exp);temp[strlen(temp)-1]='\0';
	     if(strcmp(exp,"#")==0)  return;
         if(match(exp))
         if(functionprocess(exp))
         if(transform(suffix,exp))
		 if(result=calc(suffix)){ 
	  printf("\n     结果为");
	  if(strlen(temp)<20)
      printf("%s=",temp);
      printf("%g\n\n",result);}}
	  goto loof;
 }

⌨️ 快捷键说明

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