PTA 02-線性結構2 一元多項式的乘法與加法運算 (20 分)
阿新 • • 發佈:2019-01-07
02-線性結構2 一元多項式的乘法與加法運算 (20 分)
設計函式分別求兩個一元多項式的乘積與和。
輸入格式:
輸入分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* PolyPtr;
struct PolyNode{
// expon:多項式的指數,coef多項式的係數,link是指向下一個節點的指標
int expon;
int coef;
PolyPtr link;
};
PolyPtr WritePoly()
{
// 寫入一個連結串列,返回這個連結串列的頭指標
PolyPtr front, rear;
int n, coef, expon;
scanf("%d", &n);
front = (PolyPtr)malloc(sizeof(struct PolyNode));
front->link = NULL;
rear = front;
while(n--){
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
scanf("%d %d", &coef, &expon);
p->coef = coef;
p->expon = expon;
p->link = NULL;
front->link = p;
front = p;
}
return rear;
}
void ReadPoly(PolyPtr tmp)
{
// 讀出一個連結串列,若連結串列的第一個元素是空,則輸出0 0
if(tmp->link)
{
printf("%d %d", tmp->link->coef, tmp->link->expon);
tmp = tmp->link;
while(tmp->link){
tmp=tmp->link;
printf(" %d %d", tmp->coef, tmp->expon);
}
}
else{
printf("0 0");
}
printf("\n");
}
PolyPtr mults(PolyPtr p1, PolyPtr p2)
{
// 乘法
if(!p1->link || !p2->link) {
// 如果某個連結串列的頭指標是空的,則返回一個空的頭指標
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
p->expon=0;
p->coef=0;
p->link=NULL;
return p;
}
PolyPtr result_front, result_rear, s1=p1, s2=p2;
result_front = (PolyPtr)malloc(sizeof(struct PolyNode));
result_front->link = NULL;
result_rear = result_front;
// 初始化乘法多項式,用s2的每一項乘以s1的每一項
while(s2->link)
{
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
int coef=s1->link->coef*s2->link->coef, expon=s1->link->expon+s2->link->expon;
p->coef = coef; p->expon = expon; p->link = NULL;
result_front->link = p;
result_front = p;
s2 = s2->link;
}
s1 = s1->link;
// 兩重迴圈,用s2的每一項乘s1的每一項
while(s1->link)
{
s2 = p2;
while(s2->link)
{
result_front = result_rear;
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
int coef=s1->link->coef*s2->link->coef, expon=s1->link->expon+s2->link->expon;
p->expon = expon;
p->coef = coef;
p->link = NULL;
// 找到指數不大於當前要插入的節點的指數的位置
while(result_front->link && result_front->link->expon>expon)
result_front = result_front->link;
if(result_front->link && result_front->link->expon<expon){
// 找到了要插入的位置,並且不是連結串列的最後,則插入
p->link = result_front->link;
result_front->link = p;
}
else if(result_front->link && result_front->link->expon==expon)
{
if(result_front->link->coef+coef)
{
//係數相加不為0,則改變這個係數
result_front->link->coef += coef;
}
else{
//係數相加為0,則刪除當前節點
PolyPtr tmp;
tmp = result_front->link;
result_front->link = tmp->link;
free(tmp);
}
}
else{
// 當前係數是最小的,要插入到這個連結串列的最後
result_front->link = p;
}
s2 = s2->link;
}
s1=s1->link;
}
return result_rear;
}
PolyPtr sums(PolyPtr p1, PolyPtr p2)
{
// 加法
PolyPtr result_front, result_rear;
result_front = (PolyPtr)malloc(sizeof(struct PolyNode));
result_front->link = NULL;
result_rear = result_front;
int flag;
while(p1->link && p2->link)
{
flag=1;
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
// 比較兩個節點的指數的大小,插入指數較大的那個
if(p1->link->expon>p2->link->expon)
{
p->expon = p1->link->expon;
p->coef = p1->link->coef;
p1=p1->link;
}
else if(p1->link->expon<p2->link->expon)
{
p->expon = p2->link->expon;
p->coef = p2->link->coef;
p2 = p2->link;
}
else
{
if(p1->link->coef+p2->link->coef)
{
p->coef = p1->link->coef+p2->link->coef;
p->expon = p1->link->expon;
p1=p1->link;
p2=p2->link;
}
else {
flag=0;
p1=p1->link;
p2=p2->link;
}
}
if(flag)
{
result_front->link=p;
result_front=p;
}
}
// 將剩下的沒有遍歷完的一個連結串列直接鏈在結果後面
result_front->link = p1->link?p1->link:p2->link;
return result_rear;
}
int main()
{
PolyPtr p1, p2, mult_p, sum_p;
p1 = WritePoly();
//ReadPoly(p1);
p2 = WritePoly();
// ReadPoly(p1);
// ReadPoly(p2);
mult_p = mults(p1, p2);
ReadPoly(mult_p);
sum_p = sums(p1, p2);
ReadPoly(sum_p);
}
/*
4 3 4 -5 2 -3 1 -2 0
3 5 20 -7 4 3 1
*/