链表练习:多项式的加法和乘法
题目要求
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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
分析
首先,确定程序的函数种类。显然,我们需要加法函数Add和乘法函数Multi。其次,需要读入多项式的函数Read和输出多项式的函数Print_Polynomial。由于输入的时候是由指数递减顺序一项一项地读入,且我们是通过链表存储多项式的,因此必须有一个函数Attach,将刚刚收到的新项接在已经收到的项的后面。根据这些函数,可以确定main函数的构成:
typedef struct Polynode *Polynomial;
typedef struct Polynode
{
int coe;
int exp;
Polynomial next;
}PNode;
...
int main()
{
Polynomial p1, p2, pm, pa;
p1 = Read();
p2 = Read();
pm = Multi(p1, p2);
Print_Polynomial(pm);
pa = Add(p1, p2);
Print_Polynomial(pa);
return 0;
}
Read 函数的实现
基本思路是:首先,读入待读入多项式的项数N,然后做N次循环,每次循环读入这一项的系数coe和指数exp。之后使用Attach函数将这一项接到已经存在的项的后面。
Polynomial Read()
{
Polynomial p, rear, temp;
int N, coe, exp;
// printf("Please input the number of terms of the polynomial\n");
scanf("%d", &N);
p = (Polynomial)malloc(sizeof(PNode));
p -> next = NULL;
rear = p;
while(N --)
{
scanf("%d %d", &coe, &exp);
Attach(coe, exp, &rear);
}
temp = p;
p = p -> next;
free(temp);
return p;
}
Attach 函数实现
思路:申请一个空节点,将该节点赋值后接入原链表尾部
void Attach(int coefficient, int exponent, Polynomial *rear)
{
Polynomial p;
p = (Polynomial)malloc(sizeof(PNode));
p -> coe = coefficient;
p -> exp = exponent;
p -> next = NULL;
(*rear) -> next = p;
*rear = p;
}
Print_Polynomial函数实现
void Print_Polynomial(Polynomial p)
{
int flag = 0;
if(!p)
{
printf("0 0\n");
return;
}
while(p)
{
if(!flag)
flag = 1;
else
printf(" ");
printf("%d %d", p -> coe, p -> exp);
p = p -> next;
}
printf("\n");
}
Add函数实现
思路:申请一个空链表,逐项比较两个待加链表每一项的指数大小,将指数大的那一项移入新链表并且工作指针后移继续比较。若指数一样大,则需判定系数之和是否为零,若为零,则不用考虑该项,若不为零,则将两项的系数相加,指数不变地移入新链表。一旦有一个链表的工作指针走到最后,就将另一个链表直接全部移入新链表。
Polynomial Add(Polynomial p1, Polynomial p2)
{
Polynomial p, rear, temp_1, temp_2, temp;
p = (Polynomial)malloc(sizeof(PNode));
rear = p;
temp_1 = p1;
temp_2 = p2;
while(temp_1 && temp_2)
{
if(temp_1 -> exp + temp_2 -> exp)
{
if(temp_1 -> exp > temp_2 -> exp)
{
Attach(temp_1 -> coe, temp_1 -> exp, &rear);
temp_1 = temp_1 -> next;
}
else if(temp_1 -> exp < temp_2 -> exp)
{
Attach(temp_2 -> coe, temp_2 -> exp, &rear);
temp_2 = temp_2 -> next;
}
else
{
Attach(temp_1 -> coe + temp_2 -> coe, temp_1 -> exp, &rear);
temp_1 = temp_1 -> next;
temp_2 = temp_2 -> next;
}
}
else
{
temp_1 = temp_1 -> next;
temp_2 = temp_2 -> next;
}
}
if(!temp_1)
{
while(temp_2)
{
Attach(temp_2 -> coe, temp_2 -> exp, &rear);
temp_2 = temp_2 -> next;
}
}
if(!temp_2)
{
while(temp_1)
{
Attach(temp_1 -> coe, temp_1 -> exp, &rear);
temp_1 = temp_1 -> next;
}
}
rear -> next = NULL;
temp = p;
p = p -> next;
free(temp);
return p;
}
Multi函数实现
思路:申请一个新链表,先用第一个待乘链表的第一项乘以第二个链表的所有项,得到一个基准多项式。然后从第一个待乘链表的第二项开始,逐项乘以第二个链表的每一项,每得到一项,则比较该项指数与基准多项式的各项指数大小,将该项插入到基准多项式的某一个位置中使得新的多项式按指数递减排列。若新得到的项的指数与基准多项式中的某一项指数相等,则需判断这两项系数之和是否为0,若为0,则从基准多项式中删除该项,若不为0,则将这两项的系数相加,指数不变,更新进多项式中。
Polynomial Multi(Polynomial p1, Polynomial p2)
{
Polynomial p, rear, temp_1, temp_2, temp;
int coefficient, exponent;
if(! p1 || ! p2)
return NULL;
temp_1 = p1;
temp_2 = p2;
p = (Polynomial)malloc(sizeof(PNode));
p -> next = NULL;
rear = p;
while(temp_2)
{
coefficient = temp_1 -> coe * temp_2 -> coe;
exponent = temp_1 -> exp + temp_2 -> exp;
Attach(coefficient, exponent, &rear);
temp_2 = temp_2 -> next;
}
temp_1 = temp_1 -> next;
while(temp_1)
{
rear = p;
temp_2 = p2;
while(temp_2)
{
coefficient = temp_1 -> coe * temp_2 -> coe;
exponent = temp_1 -> exp + temp_2 -> exp;
while(rear -> next && rear -> next -> exp > exponent)
rear = rear -> next;
if(rear -> next && rear -> next -> exp == exponent)
{
if(rear -> next -> coe + coefficient)
rear -> next -> coe += coefficient;
else
{
temp = rear -> next;
rear -> next = temp -> next;
free(temp);
}
}
else
{
temp = (Polynomial)malloc(sizeof(PNode));
temp -> next = NULL;
temp -> coe = coefficient;
temp -> exp = exponent;
temp -> next = rear -> next;
rear -> next = temp;
rear = rear -> next;
}
temp_2 = temp_2 -> next;
}
temp_1 = temp_1 -> next;
}
rear -> next = NULL;
temp = p;
p = p -> next;
free(temp);
return p;
}