7-2 一元多項式的乘法與加法運算 (20 分)
這是在浙大MOOC數據結構的一道課後題,可是浪費了我很多的時間大約4,5個小時。
感覺這道題的邏輯並不複雜,也不是很難,但就是沒能構想出他的整個的運行過程,導致在編程的時候浪費了大量的時間。
總結了以下的經驗教訓:
1、儘量把功能封裝好,明確輸入輸出。完成測試。
2、做好初始化,對List的初始化。
3、在程序運行出錯時,多printf()關鍵的中間過程,就例如乘法中每一步相乘的結果(要是這裏早打印出來看看,或許能省很多時間)。
4、如果程序一直有問題,可以從頭梳理一遍程序的邏輯看哪裏有問題。
#include <stdio.h>
#include <stdlib.h>
//定義鏈表結構
typedef int ElementType;
typedef struct LNode *List;
struct LNode{
ElementType ceof; //多項式係數
ElementType expon; //多項式指數
List Next; //指向下一個結點
};
//函數定義
void Insert(ElementType ceof,ElementType expon,List Ptrl); //插入
List CreateList(); //建立空表
List multi(List p1,List p2); //乘法
List Plus(List p1,List p2); //加法
int compare(List p1,List p2); //比較指數
int main()
{
List p1,p2;
List p;
p1 = CreateList();
p2 = CreateList();
int num1,num2;
int ceof,expon;
int i;
scanf("%d",&num1);
for(i=0;i<num1;i++){
scanf("%d %d",&ceof,&expon);
Insert(ceof,expon,p1);
}
scanf("%d",&num2);
for(i=0;i<num2;i++){
scanf("%d %d",&ceof,&expon);
Insert(ceof,expon,p2);
}
//乘法
p = multi(p1->Next,p2->Next);
while(p){
if(p->Next != NULL){
printf("%d %d ",p->ceof,p->expon);
} else {
printf("%d %d\n",p->ceof,p->expon);
}
p = p->Next;
}
//實現了加法
p = Plus(p1->Next,p2->Next);
if(p){
while(p){
if(p->Next != NULL){
printf("%d %d ",p->ceof,p->expon);
} else {
printf("%d %d\n",p->ceof,p->expon);
}
p = p->Next;
}
} else { //防止出現p1,p2抵消爲零的情況
printf("0 0\n");
}
return 0;
}
//乘法,不帶頭結點
List multi(List p1,List p2){
List p,p_1,p_2,dele;
p = CreateList();
//p_1 = p1->Next;
//p_2 = p2->Next;
p_1 = p1;
p_2 = p2;
int flag = 1;
while(p_1){
List temp;
temp = CreateList();
p_2 = p2;
while(p_2){
//ElementType ceof_muti = p_1->ceof*p_2->ceof;
//ElementType expen_plus = p_1->expon+p_2->expon;
Insert((p_1->ceof*p_2->ceof),(p_1->expon+p_2->expon),temp);
p_2 = p_2->Next;
}
/* 打印中間結果temp
List temp_1 = temp;
while(temp_1) {
printf("%d %d ",temp_1->ceof,temp_1->expon);
temp_1 = temp_1->Next;
}
printf("\n");*/
temp = temp->Next; //去除頭節點
if(flag){
while(temp){
Insert(temp->ceof,temp->expon,p);
temp = temp->Next;
}
//因爲之前賦了初值是0;如果不消除頭指針的話
//會讓第一部分一直在隊尾
p = p->Next;
flag = 0;
} else {
p = Plus(p,temp);
}
/*打印合並後的結果p
List temp_2 = p;
while(temp_2) {
printf("%d %d ",temp_2->ceof,temp_2->expon);
temp_2 = temp_2->Next;
}
printf("\n");*/
free(temp);
p_1 = p_1->Next;
}
/* 去除頭節點,現在以用不到,前面已經去除了
//printf("multi去非零項之前:%d\n",p->ceof);
dele = p; //釋放頭指針
p = p->Next; //指向多項式的第一個非零項
free(dele);
//printf("multi去非零項之後:%d\n",p->ceof);
*/
return p;
}
//比較係數大小
int compare(List p1,List p2){
if(p1->expon > p2->expon) return 1;
else if(p1->expon < p2->expon) return -1;
else return 0;
}
//加法,傳入的不帶頭結點
List Plus(List p1,List p2){
List ptr,p_1,p_2,temp_1;
ptr = CreateList();
//p_1 = p1->Next;
//p_2 = p2->Next;
p_1 = p1;
p_2 = p2;
//printf("plus不帶頭指針p1:%d\n",p_1->ceof);
//printf("plus不帶頭指針p2:%d\n",p_2->ceof);
while(p_1 && p_2){
int temp_1 = compare(p_1,p_2);
switch(temp_1){
case 1:
Insert(p_1->ceof,p_1->expon,ptr);
p_1 = p_1->Next;
break;
case -1:
Insert(p_2->ceof,p_2->expon,ptr);
p_2 = p_2->Next;
break;
case 0:
if((p_2->ceof + p_1->ceof) == 0)
{
p_1 = p_1->Next;
p_2 = p_2->Next;
} else {
Insert((p_2->ceof + p_1->ceof),p_2->expon,ptr);
p_1 = p_1->Next;
p_2 = p_2->Next;
}
break;
default:
break;
}
}
for(;p_1;p_1=p_1->Next) Insert(p_1->ceof,p_1->expon,ptr);
for(;p_2;p_2=p_2->Next) Insert(p_2->ceof,p_2->expon,ptr);
//printf("plus去非零項之前:%d\n",ptr->ceof);
temp_1 = ptr; //釋放頭指針
ptr = ptr->Next; //指向多項式的第一個非零項
free(temp_1);
//printf("plus去非零項之後:%d\n",ptr->ceof);
return ptr;
}
//建立空表
List CreateList(){
List p;
p = (List)malloc(sizeof(struct LNode));
p->Next = NULL;
p->ceof = 0;
p->expon = 0;
return p;
}
//插入
void Insert(ElementType ceof,ElementType expon,List Ptrl){
List s,p;
p = Ptrl;
while(p->Next) p = p->Next;
s = CreateList();
s->ceof = ceof;
s->expon = expon;
p->Next = s;
}