2009年5月8日 星期五

多項式結構運算 (C)

//===============================================================
// 20090508 知識 +
// http://tw.knowledge.yahoo.com/question/question?qid=1009050803066
// 發問者 :(BNG) http://tw.knowledge.yahoo.com/my/my?show=AF03436443
//===============================================================

程式是以不定參數的方式來建立多項式, 項次的參數型態需為 double, 為方便以後使用...
程式內除了多項式的相加外, 也提供了相減 與 各項係數乘上指定常數來進行轉換.


#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

typedef struct stMultinomial
{
struct stMultinomial * Next;
int Length;
double Item[1];
}Multinomial;

Multinomial * g_First = NULL;
Multinomial * g_Last = NULL;

// 產生新的空白多項式
Multinomial * NewMultinomial(unsigned int number)
{
unsigned int i;
Multinomial * multinomial = (Multinomial *) malloc(sizeof(Multinomial)+sizeof(double)*(number-1));
multinomial->Next = NULL;
multinomial->Length = number;
for(i=0; i<number; i++)
multinomial->Item[i] = 0.;
if (g_First==NULL) g_First = multinomial;
if (g_Last!=NULL) g_Last->Next = multinomial;
g_Last = multinomial;
return multinomial;
}
// 建立多項式 : 第一個參數為含常數的數量, 之後參數需為 double 型態
Multinomial * CreateMultinomial(unsigned int number, ... )
{
unsigned int i;
Multinomial * multinomial = NewMultinomial(number);
va_list argptr;
va_start( argptr, number);
for(i=0; i<number; i++)
multinomial->Item[i]=va_arg(argptr, double);
va_end( argptr);
return multinomial;
}
// 多項式相加 A+B
Multinomial * MultinomialAdd(Multinomial *A, Multinomial *B)
{
int i;
int Max = (A->Length>B->Length)? A->Length: B->Length;
Multinomial * multinomial = NewMultinomial(Max);
for(i=0; i<Max; i++)
multinomial->Item[i]= ((i<A->Length)? A->Item[i]: 0.) + ((i<B->Length)? B->Item[i]: 0.);
return multinomial;
}
// 多項式相減 A-B
Multinomial * MultinomialSubtract(Multinomial *A, Multinomial *B)
{
int i;
int Max = (A->Length>B->Length)? A->Length: B->Length;
Multinomial * multinomial = NewMultinomial(Max);
for(i=0; i<Max; i++)
multinomial->Item[i]= ((i<A->Length)? A->Item[i]: 0.) - ((i<B->Length)? B->Item[i]: 0.);
return multinomial;
}
// 多項式換算 A = A x c
double MultinomialConversion(Multinomial *A, double c)
{
int n = A->Length;
while( --n>=0 )
{
if (A->Item[n]==0) continue;
if (c==0.) c=1./A->Item[n]; // 若 c為0 則是要約化首項
A->Item[n] *= c;
}
return (c!=0)? c: 1.;
}
// 顯示多項式
void PrintMultinomial(char *symbol, Multinomial *A)
{
char format[][16] = { "+%d.%d", "%d.%d", "+%d.%d%s", "%d.%d%s", "+%d.%d%s^%d", "%d.%d%s^%d" };
char format1[][16] = { "+%d", "%d", "+%d%s", "%d%s", "+%d%s^%d", "%d%s^%d" };
char format2[][16] = { "+%s", "%s", "+%s^%d", "%s^%d" };

int decimal, m, o=0;
int n = A->Length;
while(--n>=0)
{
if (A->Item[n]==0) continue;
m = ((n>1)? 4: n*2);
if (A->Item[n]<0 || o++==0) m++;
if (n!=0 && A->Item[n]==1.)
printf( format2[m-2], symbol, n);
else if( decimal = (int)((A->Item[n]-(int)A->Item[n])*1000000.) )
{
while( decimal%10==0) decimal/=10;
printf( format[m], (int)A->Item[n], decimal, symbol, n);
}
else printf( format1[m], (int)A->Item[n], symbol, n);
}
}
// 清除程式中所配置的記憶體
void ClearAll()
{
Multinomial * node = g_First;
Multinomial * freeNode;
for( ; (freeNode=node)!=NULL; free(freeNode))
node=node->Next;
g_First = g_Last = NULL;
}
//=========== 主程式
int main()
{
//A(X)= 7x^5 +3x^2+8
//B(X)= 5x^6+2x^5+9X^2+x+12
//C(X) = 5X^6+9X^5+12X^2+X+20

// 需注意下面設定多項式: 第一個參數為含常數的數量, 之後參數須為 double 型態
Multinomial * A = CreateMultinomial( 6, 8., 0., 3., 0., 0., 7. );
Multinomial * B = CreateMultinomial( 7, 12., 1., 9., 0., 0., 2., 5. );
Multinomial * C = MultinomialAdd( A, B );

printf( "\nA(x) = " );
PrintMultinomial( "x", A );
printf( "\nB(x) = " );
PrintMultinomial( "x", B );
printf( "\nC(x) = A(x)+B(x) = " );
PrintMultinomial( "x", C );

double d = MultinomialConversion( C, 0.);
printf( "\n Conversion C(x)*%f = ", d);
PrintMultinomial( "x", C );

ClearAll();
return 0;
}
//=================================




~~~~~

沒有留言:

張貼留言