用c语言实现数学多项式的计算

来源:互联网 发布:c语言打印金字塔图形 编辑:程序博客网 时间:2024/06/06 06:30

#include"stdio.h"                                                                                          
#include"stdlib.h"                                                                                         
#include"calc.h"                                                                                           
#include <math.h>                                                                                          
#define POW 1                                                                                              
#define MUL 2                                                                                              
#define DIV 3                                                                                              
#define MOD 4                                                                                              
#define DIV_INT 5                                                                                          
#define ADD 6                                                                                              
#define SUB 7                                                                                              
#define MOVEL 8                                                                                            
#define MOVER 9                                                                                            
#define BIG 10                                                                                             
#define SML 11                                                                                             
#define BIG_EQAUL 12                                                                                       
#define SML_EQAUL 13                                                                                       
#define NOT 14                                                                                             
#define EQAUL 15                                                                                           
#define BIT_AND 16                                                                                         
#define DIFFER_OR 17                                                                                       
#define BIT_OR 18                                                                                          
#define AND 19                                                                                             
#define OR 20                                                                                              
#define Lp  21                                                                                             
#define Rp  22                                                                                             
#define END 23                                                                                             
#define OPSUM 23                                                                                           
#define Epsilon 0                                                                                                                                                                          
int ch_char_int(char *data);                                                                               
int ch_int_char(int data,char *parm);                                                                      
float eval(char tag,float left,float right);                                                               
int   getToken(float *nump,char *box,int *state);                                                            
int   instead(char *box,char *express,int x1,int x2,int x3, int x4);                                         
float express_calc(char *box);                                                                             
/*-------------------------------运算符号的优先级的设置--------------------------------*/                  
int osp[23] = {13,11,11,11,11,10,10,9,9,8,8,8,8,7,7,6,5,4,3,2,13,1,1};                                     
int isp[21] = {12,11,11,11,11,10,10,9,9,8,8,8,8,7,7,6,5,4,3,2,1};//主要是为了"("来设置的。                                                                                                                       
struct                                                                                                     
{                                                                                                          
 char op[2];                                                                                           
 int code;                                                                                             
}opchTbl[24] =                                                                                             
{                                                                                                          
{{'*','/0'},MUL},//11                                                                                      
{{'/','/0'},DIV},//11                                                                                      
{{'%','/0'},MOD},//11                                                                                      
{{'/','/'},DIV_INT},//11                                                                                   
{{'+','/0'},ADD},//10                                                                                      
{{'-','/0'},SUB},//10                                                                                      
{{'<','<'},MOVEL},//9                                                                                      
{{'>','>'},MOVER},//9                                                                                      
{{'>','/0'},BIG},//8                                                                                       
{{'<','/0'},SML},//8                                                                                       
{{'>','='},BIG_EQAUL},// 8                                                                                 
{{'<','='},SML_EQAUL},// 8                                                                                 
{{'!','='},NOT},// 7                                                                                       
{{'=','='},EQAUL},// 7                                                                                     
{{'&','/0'},BIT_AND},//6                                                                                   
{{'^','/0'},DIFFER_OR},//5                                                                                 
{{'|','/0'},BIT_OR},//4                                                                                    
{{'&','&'},AND},// 3                                                                                       
{{'|','|'},OR},// 2                                                                                        
{{'(','/0'},Lp},//13                                                                                       
{{')','/0'},Rp},// 1                                                                                       
{{'$','/0'},POW},//  1                                                                                     
{{'/n','/0'},END},//                                                                                       
{{' ','/0'},-1}};//                                                                                        
                                                                                                           
typedef struct node                                                                                        
{                                                                                                          
 float data;                                                                                           
 struct node *link;                                                                                    
}stack;                                                                                                    
                                                                                                           
/*----------------------------------------------                                                           
计算的方法:                                                                                                
------------------------------------------------*/                                                         
main()                                                                                                     
{                                                                                                          
   char *data = NULL;                                                                                      
   int  number=0;                                                                                          
   char box[12];                                                                                           
   int  state = 0;                                                                                         
   int  i=0;                                                                                               
   int  gt_re=0;                                                                                           
   float last_value;                                                                                       
                                                                                                           
   /*---------------------存储计算表达式-------------------*/                                              
   instead(box,"x1+(x2*x3)*0.899",11,2,1,0);                                                               
   printf(box);                                                                                            
   /*-----------------------------------------------------*/                                               
 last_value = express_calc(box);                                                                       
 printf("%f",last_value);                                                                              
}                                                                                                          
/*----------------------------------------------------------                                               
函数的功能:进入堆栈                                                                                        
相关功能的说明:                                                                                            
1,                                                                                                         
-----------------------------------------------------------*/                                              
int push_stack(float s_data,stack **stpoint)                                                               
{                                                                                                          
   stack *p =(stack *)malloc(sizeof(stack));                                                               
   p->data = s_data;                                                                                       
   p->link = *stpoint;                                                                                     
   *stpoint = p;//这样才能进行传递。                                                                       
   return 0;                                                                                               
}                                                                                                          
/*-------------------------------------------------------------------                                      
函数的功能:数据出堆                                                                                       
----------------------------------------------------------------------*/                                   
int pop_stack(float *s_data,stack **spoint)                                                                
{                                                                                                          
 stack *p = *spoint ;                                                                                  
 if( p==NULL) return -1;//没有数据栈                                                                   
 else                                                                                                  
  *s_data = p->data;                                                                               
     *spoint = p->link;                                                                                
  free(p);                                                                                         
 return 0;                                                                                             
}                                                                                                          
/*--------------------------------------------------------------------------                               
函数的名称:int instead(char *box,char *express,int x1,int x2,int x3, int x4)                              
函数的参数:char *box用来存储结果                                                                          
            char *express计算的表达式                                                                      
   x1..4计算表达式的参数1                                                                      
函数的返回值:0表示函数执行的是正确的。                                                                     
函数的功能:用参数代替标号                                                                                  
           注意express表达式由x1,x2,x3,x4和运算符号                                                        
     '+''-''*''/'()组成                                                                            
     "x1+x2*(x3+x4%5)"                                                                             
--------------------------------------------------------------------------*/                               
int instead(char *box,char *express,int x1,int x2,int x3, int x4)                                          
{                                                                                                          
 int i=0;                                                                                              
 int length=0;                                                                                         
    int box_i=0;                                                                                           
 int data=0;                                                                                           
 do                                                                                                    
 {                                                                                                     
  length++;                                                                                        
 }while(express[length]!='/0');                                                                        
                                                                                                           
 for(i=0;express[i]!='/0';i++,box_i++)//因为这里已经加了,所以说box_i是最后一个位置。                  
 {                                                                                                     
  box[box_i]=express[i];                                                                           
  if((express[i]=='x')&&((express[i+1]>='1')&&((express[i+1]<='4'))))                              
  {                                                                                                
                                                                                                   
   switch(express[i+1])                                                                        
   {                                                                                           
   case '1':                                                                                   
      data = x1;                                                                       
      break;                                                                           
   case '2':                                                                                   
        data =x2;                                                                          
     break;                                                                            
   case '3':                                                                                   
        data = x3;                                                                         
     break;                                                                            
   case '4':                                                                                   
        data =x4;                                                                          
     break;                                                                            
   }                                                                                           
   /*-------复合语句实现的是把数据存储在box[box_i-1]后面---------------*/                      
   {                                                                                           
    int k=0;//存储data的位数                                                               
    int temp=0;//存储data的中间变量                                                        
                int j=0;                                                                                   
    temp=data;                                                                             
    while(temp!=0)                                                                         
    {                                                                                      
     k++;                                                                              
     temp=temp/10;                                                                     
    }                                                                                      
    temp=data;                                                                             
    for(j=0;j<k;j++)                                                                       
    {                                                                                      
     box[box_i-1+k-j] = temp%10+48;                                                    
     temp=temp/10;                                                                     
    }                                                                                      
    box_i = box_i-1+k;                                                                     
   }                                                                                           
   /*-------------------------------------------------------------------*/                     
   i=i+1;                                                                                      
  }                                                                                                
 }                                                                                                     
 box[box_i]='/n';//整个计算式的最后一个字母是换行符。                                                  
 return 0;                                                                                             
}                                                                                                          
/*--------------------------------------------------------------------------                          
函数的功能:计算表达式                                                                                     
函数实现的过程:                                                                                            
----------------------------------------------------------------------------*/                        
float express_calc(char *box)                                                                              
{                                                                                                          
 int state=0;//记录box当前的位置信息                                                                   
 float number; //出堆栈的数据存储                                                                      
 float tag=0.0;                                                                                        
 float right=0.0;                                                                                      
 float left=0.0;                                                                                       
 int  gt_re_value;                                                                                     
 float last_value;                                                                                     
    stack *num_stack = NULL;//用于存放数字                                                                 
 stack *tab_stack = NULL;//用于存放计算符号                                                            
                                                                                                           
 push_stack(Lp,&tab_stack);//首先把左括号放到符号堆栈里面                                              
 while(1)                                                                                              
 {                                                                                                     
    gt_re_value=getToken(&number,box,&state);                                                          
       if(gt_re_value==0)//表示的是返回是数值                                                              
     push_stack(number,&num_stack);//存储数值                                                      
    else//返回的是标号                                                                                 
    {                                                                                                  
     if(osp[gt_re_value - 1] > isp[(int)tab_stack->data - 1])//进行优先级的判断                    
    push_stack((float)gt_re_value,&tab_stack);//对标号进行存储                             
     else                                                                                          
     {   /*--在这里进行判断*/                                                                      
      while(osp[gt_re_value - 1] <= isp[(int)tab_stack->data - 1] && tab_stack->data <= OPSUM-3)
      {                                                                                        
     if(pop_stack(&tag,&tab_stack))   return -1;                                       
     if(pop_stack(&right,&num_stack)) return -1;                                       
     if(pop_stack(&left,&num_stack))  return -1;                                       
        last_value =  eval((char)tag,left,right);                                          
     push_stack(last_value,&num_stack);                                                
      }                                                                                        
      if(gt_re_value == END) break;                                                            
      if(gt_re_value == Rp)                                                                    
      {                                                                                        
       do                                                                                  
       {                                                                                   
        if(pop_stack(&tag,&tab_stack))                                                 
        return CalcError;                                                              
       }                                                                                   
       while((char)tag != Lp);                                                             
      }                                                                                        
      else                                                                                     
     push_stack((float)gt_re_value,&tab_stack);                                        
     }                                                                                             
    }                                                                                                  
 }                                                                                                     
     if(pop_stack(&last_value,&num_stack)) return -1;                                                       
 while(num_stack != NULL) pop_stack(&number,&num_stack);                                               
 while(tab_stack != NULL) pop_stack(&number,&tab_stack);                                               
 return last_value;                                                                                    
}                                                                                                          
/*----------------------------------------------------------------------------                           
函数的功能:1,                                                                                              
------------------------------------------------------------------------------*/                           
int  getToken(float *nump,char *box,int *state)                                                            
{                                                                                                          
 float data = 0;                                                                                       
 int num = 0;                                                                                          
 int i=0;                                                                                              
 int j=0;                                                                                              
 int flag=0;                                                                                           
 while((box[*state]<'0')||(box[*state]>'9'))                                                           
 {                                                                                                     
  for(i=0;i<OPSUM-1;i++)                                                                           
  {                                                                                                
   if(opchTbl[i].op[0]==box[*state])                                                           
   {                                                                                           
    for(j=0;j<OPSUM-1;j++)                                                                 
    {                                                                                      
     if((opchTbl[j].op[0]==box[*state])&&(opchTbl[j].op[1]==box[*state+1]))            
     {                                                                                 
      flag=1;//说明是双目运算                                                      
     }                                                                                 
    }                                                                                      
       if(j==(OPSUM-1)) flag=0;//说明是单目运算符                                                  
    break;                                                                                 
   }                                                                                           
  }                                                                                                
  if(flag==1) *state = *state + 2;                                                                 
  if(flag==0) *state = *state +1;                                                                  
                                                                                                           
  if(i==OPSUM-1)                                                                                   
  {                                                                                             
   if(opchTbl[i].op[0]=='/n')//说明是最后一个                                                  
   {                                                                                           
    return opchTbl[i].code;                                                                
   }                                                                                           
   else return -1;//表示的是表达式是错误的                                                     
  }                                                                                                
  return opchTbl[i].code;                                                                          
 }                                                                                                     
                                                                                                           
 while((box[*state]>='0')&&(box[*state]<='9'))//说明是一个字                                           
 {                                                                                                     
  data = data*10 + box[*state] - '0';                                                              
        *state = *state + 1;                                                                               
 }                                                                                                     
 if(box[*state]=='.')                                                                                  
 {                                                                                                     
  *state = *state+1;                                                                               
  {                                                                                                
   int dex=10;                                                                                 
   float  count_down = (float)1/dex;                                                           
   while((box[*state]>='0')&&(box[*state]<='9'))                                               
   {                                                                                           
    data = ((float)(box[*state]-'0'))*(count_down) + data;                                 
    count_down = count_down/dex;                                                           
    *state = *state+1;                                                                     
   }                                                                                           
  }                                                                                                
 }                                                                                                     
 //printf("%f",data);                                                                                  
 *nump = data;                                                                                         
 return 0;//0表示的是返回的是值。                                                                      
}                                                                                                          
/*---------------------------------------------------------------------------                        
函数的功能是实现:左值和右值的计算                                                                          
-----------------------------------------------------------------------------*/                       
float eval(char tag,float left,float right)                                                                
{                                                                                                          
 int n;                                                                                                
 float result;                                                                                         
 switch(tag)                                                                                           
 {                                                                                                     
 case POW :                                                                                            
  for(n = 1,result = left;n < right;n++)                                                           
   result *= left;                                                                             
  return result;                                                                                   
 case ADD: return left + right;                                                                        
 case SUB: return left - right;                                                                        
 case MUL: return left * right;                                                                        
 case MOD: return (float)((int)left % (int)right);                                                     
 case DIV:                                                                                             
  if(fabs(right) <= Epsilon)                                                                       
  {                                                                                                
   printf("除0出错!/n");                                                                       
   exit(1);                                                                                    
  }                                                                                                
  return left/right;                                                                               
 case DIV_INT:                                                                                         
  if(fabs(right) <= Epsilon)                                                                       
  {                                                                                                
   printf("除0出错!/n");                                                                       
   exit(1);                                                                                    
  }                                                                                                
  return (float)((int)left/(int)right);                                                            
 case BIG: return (float)(left > right?1:0);                                                           
 case SML: return (float)(left < right?1:0);                                                           
 case EQAUL: return (float)(left == right?1:0);                                                        
 case NOT: return (float)(left != right?1:0);                                                          
 case AND: return (float)(left && right);                                                              
 case OR: return (float)(left || right);                                                               
 case MOVEL: return (float)((int)left <<(int) right);                                                  
 case MOVER: return (float)((int)left >> (int)right);                                                  
 case BIG_EQAUL: return (float)((left > right) || (left == right));                                    
 case SML_EQAUL: return (float)((left < right) || (left == right));                                    
 case BIT_AND: return (float)((int)left & (int)right);                                                 
 case DIFFER_OR: return (float)((int)left ^ (int)right);                                               
 case BIT_OR: return (float)((int)left | (int)right);                                                  
                                                                                                   
 }                                                                                                     
 printf("表达式有错!/n");                                                                              
 return 1.0;                                                                                           
}

原创粉丝点击