您的位置:首页 > 编程语言 > C语言/C++

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

2011-02-10 20:22 686 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: