题目要求:设计函数分别求两个一元多项式的乘积与和。
输入格式:输入分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
思路:加法的实现比较简单,设置两个指针分别指向两个多项式链表第一项,哪个多项式当前项系数大,就把那一项加入到结果多项式中,然后令加入的那一项所属的多项式的指针移向下一项;如果指数相同,就使系数相加,然后加入到结果多项式中,然后令两个多项式的指针都移向下一项。乘法比较复杂,我采取的方法是用其中一多项式的每一项去分别乘另一多项式的每一项,将每次相乘结果加入到结果多项式中,但是注意:每次插入都要满足指数递减的顺序,即要插入到不比自己指数大的最小指数项前面,如果发现有指数相同的项,就直接使系数相加即可。输出的时候要注意,由于链表中存在系数为0的项,按题目要求应当去除,所以不应输出,当多项式每一项都为0时,应直接输出“0 0”,这要进行讨论。
代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct polynomial* PolyN;
typedef struct polynomial {
int coef, expon;
PolyN next;
}Polynomial;
PolyN readPolynomial();
PolyN makeSum(PolyN, PolyN);
PolyN makeProduct(PolyN, PolyN);
PolyN insert(PolyN, PolyN);
void printPolynomial(PolyN);
int main()
{
PolyN p1, p2, prod, sum;
p1 = readPolynomial();
p2 = readPolynomial();
prod = makeProduct(p1, p2);
sum = makeSum(p1, p2);
printPolynomial(prod);
printf("\n");
printPolynomial(sum);
return 0;
}
PolyN readPolynomial()
{
int num, coef, expon; scanf("%d", &num);
PolyN head = 0, tail = 0, node = 0;
while (num--)
{
node = (PolyN)malloc(sizeof(Polynomial));
scanf("%d %d", &node->coef, &node->expon);
if (!head)
head = node;
if (tail)
tail->next = node;
tail = node;
tail->next = 0;
}
return head;
}
PolyN makeSum(PolyN p1, PolyN p2)
{
if (!p1 && !p2) return 0; //如果两多项式都为零多项式直接返回零多项式
else if ((p1 && !p2) || (!p1 && p2)) return p1 ? p1 : p2; //如果其中一个多项式为零多项式则直接返回非零多项式即可
PolyN ptr1 = p1, ptr2 = p2, sum = 0, * ptr = 0; //ptr是指向sum的next的指针,所以是二级指针
while (ptr1 && ptr2)
{
if (!sum) {
sum = (PolyN)malloc(sizeof(Polynomial));
ptr = ∑
}
else
*ptr = (PolyN)malloc(sizeof(Polynomial));
if (ptr1->expon > ptr2->expon)
{
(*ptr)->coef = ptr1->coef; (*ptr)->expon = ptr1->expon;
ptr = &(*ptr)->next;
ptr1 = ptr1->next;
}
else if (ptr1->expon < ptr2->expon)
{
(*ptr)->coef = ptr2->coef; (*ptr)->expon = ptr2->expon;
ptr = &(*ptr)->next;
ptr2 = ptr2->next;
}
else
{
(*ptr)->coef = ptr1->coef + ptr2->coef; (*ptr)->expon = ptr1->expon;
ptr = &(*ptr)->next;
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
}
ptr1 = ptr1 ? ptr1 : ptr2;
*ptr = NULL;
while (ptr1)
{
*ptr = (PolyN)malloc(sizeof(Polynomial));
(*ptr)->coef = ptr1->coef;
(*ptr)->expon = ptr1->expon;
ptr1 = ptr1->next;
(*ptr)->next = NULL;
}
return sum;
}
PolyN makeProduct(PolyN p1, PolyN p2)
{
if (!p1 || !p2) return 0;
PolyN ptr1 = p1, ptr2 = p2, prod = 0;
while (ptr1)
{
while (ptr2)
{
Polynomial node; //建立临时节点储存结果
node.coef = ptr1->coef * ptr2->coef;
node.expon = ptr1->expon + ptr2->expon;
prod = insert(prod, &node); //插入
ptr2 = ptr2->next;
}
ptr1 = ptr1->next;
ptr2 = p2;
}
return prod;
}
PolyN insert(PolyN prod, PolyN next)
{
if (!prod) { //如果结果为空,直接插入即可
prod = (PolyN)malloc(sizeof(Polynomial));
prod->coef = next->coef;
prod->expon = next->expon;
prod->next = 0;
}
else {
PolyN pre, cur = prod;
for (; cur && cur->expon > next->expon; pre = cur, cur = cur->next); //寻找插入点
if (!cur) { //如果发现应当插入到表末
pre->next = (PolyN)malloc(sizeof(Polynomial));
pre->next->coef = next->coef;
pre->next->expon = next->expon;
pre->next->next = NULL;
}
else if (cur->expon == next->expon) //发现指数相同项直接系数相加
cur->coef += next->coef;
else { //插入到两节点之间
pre->next = (PolyN)malloc(sizeof(Polynomial));
pre->next->coef = next->coef;
pre->next->expon = next->expon;
pre->next->next = cur;
}
}
return prod;
}
void printPolynomial(PolyN p)
{
PolyN read = p; int flag = 0, cnt = 0;
while (read) //先遍历一遍,看是否所有项均为0
{
if (read->coef != 0) {
flag = 1;
break;
}
read = read->next;
}
read = p;
while (read && flag) //存在非零项则开始输出
{
if (!cnt && read->coef != 0) { //为了处理行末空格的问题,先输出第一个系数非零项
printf("%d %d", read->coef, read->expon);
cnt++;
}
else if (cnt && read->coef != 0) { //其后的系数非零项先输出空格再输出数据
printf(" %d %d", read->coef, read->expon);
}
read = read->next;
}
if (!flag) //如果是零多项式直接输出"0 0"
printf("0 0");
}