1. 程式人生 > >PTA||02-線性結構2 一元多項式的乘法與加法運算

PTA||02-線性結構2 一元多項式的乘法與加法運算

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

輸入格式:

輸入分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
/*
	Name: 一元多項式的乘法與加法運算 
	Copyright: 
	Author: xuuyann 
	Date: 19/10/18 11:23
	Description: 
*/

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

struct PolyNode{
	int coef;//係數
	int expon;//指數
	struct PolyNode *link;//指向下一個結點的指標 
};
typedef struct PolyNode *Polynomial;
Polynomial P1, P2;

Polynomial Read();//讀入多項式,返回多項式的頭結點 
Polynomial PolyAdd(Polynomial P1, Polynomial P2);//多項式相加
Polynomial PolyMultiply(Polynomial P1, Polynomial P2);//多項式相乘
int Compare(int e1, int e2);//比較兩多項式各項指數的大小
void Attach(int coef, int expon, Polynomial *PtrRear);
//將係數coef和指數expon構成的新項加入結果多項式的末端,同時改變當前結果多項式末尾指標PtrRear 
void Write(Polynomial P);


int main()
{
	Polynomial P1, P2;
	Polynomial AddResult, MulResult;
	P1 = Read();
	P2 = Read();//P1,P2均指向多項式連結串列中的第一個非零結點 
	MulResult = PolyMultiply(P1, P2);
	Write(MulResult);
	printf("\n");
	AddResult = PolyAdd(P1, P2);
	Write(AddResult);
	
	return 0;
}

                                                     
Polynomial Read()
//傳遞進來的是多項式非零項的個數,返回多項式頭結點 
{
	Polynomial rear, front, temp;
	int i,N;
	int c,e;
	scanf("%d",&N);
	//建立一個新的空表頭 
	rear = (Polynomial)malloc(sizeof(struct PolyNode));
	front = rear;//由front記錄多項式連結串列表頭結點 
	for (i=0 ;i<N ;i++){
		scanf("%d %d",&c ,&e );
		if (c != 0) Attach(c ,e ,&rear);
	}
	rear->link = NULL;
	temp = front;
	front = front->link ;//令front指向多項式第一個非零項
	free (temp);
	
	return front; 
}

int Compare(int e1, int e2)
//比較兩項指數e1和e2的大小,根據大、小、相等三種情況分別返回1,-1, 0 
{
	if (e1 > e2) return 1;
	else if (e1 == e2) return 0;
	else return -1;
}

Polynomial PolyAdd(Polynomial P1, Polynomial P2)
//將兩個多項式相加 
{
	Polynomial front, rear, temp;
	rear = (Polynomial)malloc(sizeof(struct PolyNode));
	front = rear;
	while (!P1 && !P2){  //兩多項式為空 
		front->coef = 0;
		front->expon = 0;
		front->link = NULL;
	}
	while (P1 && P2){   //當P1與P2均指向非零項 
		//判斷P1所指向的指數與P2所指向的指數大小
		if (Compare(P1->expon ,P2->expon ) == 1){ //e1大於e2 
			Attach(P1->coef ,P1->expon ,&rear);    //將P1放入結果多項式連結串列中 
			P1 = P1->link;   //P1指向下一個結點 
		}
		else if (Compare(P1->expon ,P2->expon ) == -1){
		 	Attach(P2->coef ,P2->expon ,&rear);  //將P2放入結果多項式連結串列中 
			P2 = P2->link;	
		}else{
			if (P1->coef + P2->coef ) Attach(P1->coef + P2->coef ,P1->expon ,&rear); //將兩項和放入結果多項式連結串列中
			P1 = P1->link;
			P2 = P2->link; //P1和P2均指向下一個結點 
		}
	}
	//P1為空並且P2不為空,將P2剩餘結點插入結果多項式中 
	for ( ;P2 ;P2 = P2->link )
		Attach(P2->coef ,P2->expon ,&rear);
	//P2為空並且P1不為空,將P1剩餘結點插入結果多項式中 
	for ( ;P1 ;P1 = P1->link )
		Attach(P1->coef ,P1->expon ,&rear);
	rear->link = NULL;
	temp = front;
	front = front->link ;
	free(temp);
	
	return front;
} 

Polynomial PolyMultiply(Polynomial P1, Polynomial P2)
{
	Polynomial front, rear, temp,temp_1,temp_2, newNode;
	rear = (Polynomial)malloc(sizeof(struct PolyNode));
	front = rear;
	while (!P1 || !P2){
		return NULL;
	} 
	temp_1 = P1;
	temp_2 = P2;
	while (temp_2){
		Attach((temp_1->coef )*(temp_2->coef ),temp_1->expon + temp_2->expon ,&rear); //相乘結果得到的項插入結果多項式中 
		temp_2 = temp_2->link;
	}
	temp_1 = temp_1->link ;   //temp_1指向P1的下一個結點 
	while (temp_1){
		rear = front;
		temp_2 = P2;
		while (temp_2){
			int c = temp_1->coef * temp_2->coef ;  //當前項係數 
			int e = temp_1->expon + temp_2->expon ;  //當前項指數 
			//與當前結果多項式中的每一項的指數進行比較,找到相應位置後插入
			while (rear->link&&rear->link->expon > e){ //當前結果多項式中某一項指數大於當前項指數 
				 rear = rear->link ;
			}
			/************************************************
			下面有種情況:1.當前項指數大於結果中的某一項指數 
						2.當前項指數等於結果中的某一項指數
						3.當前項指數最小 
			**************************************************/
			if ((rear->link && rear->link->expon < e) || !(rear->link)){
				newNode = (Polynomial)malloc(sizeof(struct PolyNode));
				newNode->coef = c;  //插入新結點 
				newNode->expon = e;
				newNode->link = rear->link ;
				rear->link = newNode;   //rear沒變
				rear = rear->link ;
			}else if (rear->link && rear->link->expon == e){  //指數相等,係數相加 
				rear->link->coef += c;
				if (!c){     //若係數相加為0 
					Polynomial t;
					t = rear->link ;
					rear->link =t->link ;
					free(t);
				}
			}	
			temp_2 = temp_2->link ;
		}
		temp_1 = temp_1->link ;
	}
	temp = front;
	front = front->link;
	free(temp);	
	
	return front;
}

void Attach(int coef, int expon, Polynomial *PtrRear)
//將即將插入結果多項式中的每一項連線起來 
{
	Polynomial temp;
	temp = (Polynomial)malloc(sizeof(struct PolyNode));
	temp->coef = coef;
	temp->expon = expon;
	temp->link = NULL;
	(*PtrRear)->link = temp;
	*PtrRear = temp;
}

void Write(Polynomial P)
{
	if (!P) printf("0 0");
	while (P){
		if (!(P->link)){
			printf("%d %d",P->coef ,P->expon );
			break;
		}
		printf("%d %d ",P->coef ,P->expon );
		
		P = P->link ;
	}
}

測試點:同類項合併時有抵消 未通過