1. 程式人生 > >02-線性結構2 一元多項式的乘法與加法運算(C語言 + 註釋)

02-線性結構2 一元多項式的乘法與加法運算(C語言 + 註釋)

設計函式分別求兩個一元多項式的乘積與和。

輸入格式:

輸入分2行,每行分別先給出多項式非零項的個數,再以指數遞降方式輸入一個多項式非零項係數和指數(絕對值均為不超過1000的整數)。數字間以空格分隔。

輸出格式:

輸出分2行,分別以指數遞降方式輸出乘積多項式以及和多項式非零項的係數和指數。數字間以空格分隔,但結尾不能有多餘空格。零多項式應輸出0 0

輸入樣例:

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

輸出樣例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

關鍵之處:

程式碼:

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

typedef struct PolyNode *Polynomial;
struct PolyNode {
	int coef;
	int expon;
	Polynomial link;
};

void Attach( int c, int e, Polynomial *pRear );
Polynomial ReadPoly();
Polynomial Add( Polynomial P1, Polynomial P2 );
int Compare( int e1, int e2 );
Polynomial Mult( Polynomial P1, Polynomial P2 );
void PrintPoly( Polynomial P );

int main(void){
	int M, N;
	Polynomial P1, P2, PP, PS;
	
	P1 = ReadPoly();
	P2 = ReadPoly();
	
	PP = Mult( P1, P2 );
	PrintPoly( PP );
	
	PS = Add( P1, P2 );
	PrintPoly( PS );
	
	return 0;
}
/*讀入多項式*/
Polynomial ReadPoly() {
	Polynomial P, Rear, t;
	int N, c, e;
	
	scanf("%d", &N);    //多項式的項數。
        /*因為Rear的初值不知道,所以我們另它指向一個空結點*/
        /*若Rear設為NULL,則Attach中要做不同處理,不方便*/
	P = (Polynomial)malloc(sizeof(struct PolyNode));    //申請一個臨時結點P.
	P->link = NULL;    //將P置空。
	Rear = P;    //尾指標指向P,因為要從尾巴插入連結串列。
	
	while( N-- ) {
		scanf("%d %d", &c, &e);    //讀入係數、指數。
		Attach( c, e, &Rear );    //Attach()函式用來連結結點。
	}
	t = P;	P = P->link; free(t);    //釋放臨時結點P
	
	return P;    //返回插入好的連結串列。
}
/*連結結點的函式,傳入的是尾指標Rear的地址,可以直接改變Rear*/
void Attach( int c, int e, Polynomial *pRear ) {
	Polynomial P; 
	
	P = (Polynomial)malloc(sizeof(struct PolyNode));    //申請一個新的結點空間。
	P->coef = c;    
	P->expon = e;    
	P->link = NULL;    
	(*pRear)->link = P;    //*pRear表示傳進來的尾指標本身,將尾指標指向新結點P.
	*pRear = P;    //此時P變成最後一個結點,尾指標指向它。
}
/*多項式相加*/
Polynomial Add( Polynomial P1, Polynomial P2 ) {
	Polynomial P, rear, temp, t1, t2;
	int sum;
	
	t1 = P1, t2 = P2;
        /*P的作用跟上面一樣,讓尾指標一開始有處可去*/
	P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->link = NULL;
	rear = P;
	while ( t1 && t2 )    //兩組多項式都非空。
		switch ( Compare(t1->expon, t2->expon) ) {    //先比較指數大小。
			case 1:    //t1指數大,鏈入t1.
				Attach( t1->coef, t1->expon, &rear );
				t1 = t1->link;    //t1結點往後挪一個。
				break;    //退出switch.
			case -1:    //t2指數大,鏈入t2.
				Attach( t2->coef, t2->expon, &rear );
				t2 = t2->link;    //t2結點往後挪一個。
				break;
			case 0:    //t1與t2指數相等的情況。
				sum = t1->coef + t2->coef;    //指數相等時,係數要相加。
				if ( sum )	Attach( sum, t1->expon, &rear );    //和不等於0,才鏈入。
				t1 = t1->link;    //t1記得向後挪一個。
				t2 = t2->link;    //t2也要向後挪一個。
				break;
		}
        /*t2完畢,t1未完,t1全部鏈入*/
	for ( ; t1; t1 = t1->link )	Attach( t1->coef, t1->expon, &rear );
        /*t1完畢,t2未完,t2全部鏈入*/
	for ( ; t2; t2 = t2->link )	Attach( t2->coef, t2->expon, &rear );
	rear->link = NULL;    //將相加後的連結串列最後一個元素指向NULL。
	temp = P;	P = P->link;	free(temp);    //釋放臨時結點P.
		
	return P;    //返回相加好的連結串列。
}
/*比較指數大小*/
int Compare( int e1, int e2 ) {
	if ( e1 > e2 )	return 1;
	else if ( e1 == e2 )	return 0;
	else	return -1;
}
/*多項式相乘*/
Polynomial Mult( Polynomial P1, Polynomial P2 ) {
	Polynomial P, Rear, t1, t2, t;
	int c, e;
	
	if ( !P1 || !P2 )	return NULL;    //多項式有一個為空,就直接返回NULL.
	
	t1 = P1, t2 = P2;
	P = (Polynomial)malloc(sizeof(struct PolyNode));
	P->link = NULL;
	Rear = P;
	
	while ( t2 ) {    //t1的第一項乘以t2的每一項。
		Attach( t1->coef * t2->coef, t1->expon + t2->expon, &Rear );
		t2 = t2->link;
	}
	
	t1 = t1->link;    
	while ( t1 ) {    //把t1的每一項乘t2的每一項。
		t2 = P2;
		Rear = P;
		while( t2 ) {
			e = t1->expon + t2->expon;    //當前兩項,指數相加。
			c = t1->coef * t2->coef;    //當前兩項,係數相乘。
			while( Rear->link && Rear->link->expon > e )
				Rear = Rear->link;
			if ( Rear->link && Rear->link->expon == e ) {
				if ( Rear->link->coef + c )
					Rear->link->coef += c;
				else {
					t = Rear->link;
					Rear->link = t->link;
					free(t);
				}
			} else {
				t = (Polynomial)malloc(sizeof(struct PolyNode));
				t->coef = c;
				t->expon = e;
				t->link = Rear->link;
				Rear->link = t; 
			}
			t2 = t2->link;
		}
		t1 = t1->link;
	}
	t = P;	
	P = P->link;	
	free( t );
	
	return P;
}

void PrintPoly( Polynomial P ) {
	int flag = 0;    //控制空格。
	
	if ( !P ) {    //如果P是空的,直接輸出0 0.
		printf("0 0\n");
		return;
	}
	while ( P ) {    //遍歷連結串列列印之。
		if ( !flag )	flag = 1;
		else	printf(" ");
		printf("%d %d", P->coef, P->expon);
		P = P->link;
	}
	printf("\n");
}