设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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<iostream>
using namespace std;
typedef struct List {
int xi;
int zhi;
struct List* next;
}Node;
List* creatList() {
List* newList = (List*)malloc(sizeof(struct List));
newList->next = NULL;
return newList;
}
Node* creatNode(int xi, int zhi) {
Node* newNode= (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
return newNode;
}
void print(List* list) {
int flag = 1;
Node* curNode = list->next;
while (curNode) {
if (flag) {
printf("%d %d", curNode->xi, curNode->zhi);
flag = 0;
}
else {
printf(" %d %d", curNode->xi, curNode->zhi);
}
curNode = curNode->next;
}
putchar('\n');
}
List* addLists(List* list1, List* list2) {
List* newList = creatList();
Node* curNode = newList;
Node* curNode1 = list1->next;
Node* curNode2 = list2->next;
int xi, zhi;
while (curNode1 && curNode2) {
if (curNode1->zhi == curNode2->zhi) {
xi = curNode1->xi + curNode2->xi;
zhi = curNode1->zhi;
curNode1 = curNode1->next;
curNode2 = curNode2->next;
if (xi == 0) {
continue;
}
}
else if (curNode1->zhi > curNode2->zhi) {
xi = curNode1->xi;
zhi = curNode1->zhi;
curNode1 = curNode1->next;
}
else if (curNode1->zhi < curNode2->zhi) {
xi = curNode2->xi;
zhi = curNode2->zhi;
curNode2 = curNode2->next;
}
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode->next = newNode;
curNode = curNode->next;
}
if (curNode1) {
curNode->next = curNode1;
}
if (curNode2) {
curNode->next = curNode2;
}
if (!newList->next) {
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = 0;
newNode->zhi = 0;
newNode->next = NULL;
newList->next = newNode;
}
return newList;
}
List* mulLists(List* list1, List* list2) {
List* newList = creatList();
Node* curNode = newList;
if (list1->next == NULL || list2->next == NULL) {
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = 0;
newNode->zhi = 0;
newNode->next = NULL;
newList->next = newNode;
return newList;
}
Node* curNode1 = list1->next;
Node* curNode2 = list2->next;
int xi, zhi;
while (curNode1) {
xi = curNode1->xi * curNode2->xi;
zhi = curNode1->zhi + curNode2->zhi;
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode->next = newNode;
curNode = curNode->next;
curNode1 = curNode1->next;
}
curNode2 = curNode2->next;
Node* pre = newList;
Node* p = newList->next;
while (curNode2) {
curNode1 = list1->next;
while (curNode1) {
pre = newList;
p = newList->next;
xi = curNode1->xi * curNode2->xi;
zhi = curNode1->zhi + curNode2->zhi;
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
while (p != NULL&&p->zhi > zhi ){
pre = pre->next;
p = p->next;
}
if (p != NULL && p->zhi == zhi) {
p->xi += xi;
if (p->xi == 0) {
pre->next = p->next;
}
}
else {
newNode->next = p;
pre->next = newNode;
}
curNode1 = curNode1->next;
}
curNode2 = curNode2->next;
}
return newList;
}
int main() {
List* newList1 = creatList();
List* newList2 = creatList();
int n1,n2, xi, zhi;
Node* curNode1 = newList1;
Node* curNode2 = newList2;
scanf("%d", &n1);
while (n1--) {
scanf("%d", &xi);
scanf("%d", &zhi);
Node* newNode= (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode1->next = newNode;
curNode1 = curNode1->next;
}
scanf("%d", &n2);
while (n2--) {
scanf("%d", &xi);
scanf("%d", &zhi);
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode2->next = newNode;
curNode2 = curNode2->next;
}
print(mulLists(newList1, newList2));
print(addLists(newList1, newList2));
}
测试样例:
序号 | 输入 | 输出 | |
---|---|---|---|
0 | 4 3 4 -5 2 6 1 -2 0 | 15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1 | |
3 5 20 -7 4 3 1 | 5 20 -4 4 -5 2 9 1 -2 0 | ||
1 | 2 1 2 1 0 | 1 4 -1 0 | |
2 1 2 -1 0 | 2 2 | ||
2 | 2 -1000 1000 1000 0 | -1000000 2000 2000000 1000 -1000000 0 | |
2 1000 1000 -1000 0 | 0 0 | ||
3 | 0 | 0 0 | |
1 1 999 | 1 999 | 1 999 |
首先本题的大致框架是:
#include<iostream>
using namespace std;
typedef struct List {
int xi; //系数
int zhi; //指数
struct List* next;
}Node;
List* creatList() ; //创建链表
Node* creatNode(int xi, int zhi) ;//创建结点(这个函数没咋用,后面创建结点忘了用这个函数了)
void print(List* list);//输出
List* addLists(List* list1, List* list2) ;//加法
List* mulLists(List* list1, List* list2) ;//乘法
int main() {
}
测试点0就是输出它给的样例。
测试点1是零多项式的乘法?(大概是吧)
测试点2是加法中结果是0的情况,即题干中说的输出0 0
测试点3是有一个多项式是0的情况
创建链表,创建结点和输出就不说了,基本的链表操作。
加法比较简单,可以参考这个:
2-1 Add Two Polynomials(多项式相加)(附测试样例)
重要的是乘法:
List* mulLists(List* list1, List* list2) {
List* newList = creatList();
Node* curNode = newList;
if (list1->next == NULL || list2->next == NULL) {
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = 0;
newNode->zhi = 0;
newNode->next = NULL;
newList->next = newNode;
return newList;
}
Node* curNode1 = list1->next;
Node* curNode2 = list2->next;
int xi, zhi;
while (curNode1) {
xi = curNode1->xi * curNode2->xi;
zhi = curNode1->zhi + curNode2->zhi;
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode->next = newNode;
curNode = curNode->next;
curNode1 = curNode1->next;
}
curNode2 = curNode2->next;
Node* pre = newList;
Node* p = newList->next;
while (curNode2) {
curNode1 = list1->next;
while (curNode1) {
pre = newList;
p = newList->next;
xi = curNode1->xi * curNode2->xi;
zhi = curNode1->zhi + curNode2->zhi;
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
while (p != NULL&&p->zhi > zhi ){
pre = pre->next;
p = p->next;
}
if (p != NULL && p->zhi == zhi) {
p->xi += xi;
if (p->xi == 0) {
pre->next = p->next;
}
}
else {
newNode->next = p;
pre->next = newNode;
}
curNode1 = curNode1->next;
}
curNode2 = curNode2->next;
}
return newList;
}
List* newList = creatList();
Node* curNode = newList;
创建一个空表,用一个指针指向空表。
指针的作用是指向尾结点,实现尾插
if (list1->next == NULL || list2->next == NULL) {
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = 0;
newNode->zhi = 0;
newNode->next = NULL;
newList->next = newNode;
return newList;
}
这段是判断时否有乘0的情况。因为乘零的结果是零。我们要输出0 0,所以要特别判断
Node* curNode1 = list1->next;
Node* curNode2 = list2->next;
int xi, zhi;
两个指针分别指向两个要进行运算的表
变量xi与zhi临时保存运算所得的值。
首先我们先用list1的第一个结点的数和list2的所有结点的数分别乘一次,得出结果。
之前我们cueNode2指向的是list2的第一个结点:
Node* curNode2 = list2->next;
while (curNode1) {
xi = curNode1->xi * curNode2->xi; //运算
zhi = curNode1->zhi + curNode2->zhi; //运算
//创建新节点
//这里忘了用creatNode函数
Node* newNode = (List*)malloc(sizeof(struct List));
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
curNode->next = newNode;
curNode = curNode->next;
curNode1 = curNode1->next;
}
先运算一次的原因是,我们最后要按指数递减的方式输出。进行下面的运算就要依次判断,找到合适位置插入。
不要忘了将指向list2的指针往后移一位:
curNode2 = curNode2->next;
Node* pre = newList;
Node* p = newList->next;
这两个指针的作用是找插入位置时,方便进行插入操作。
while (curNode2) {
curNode1 = list1->next;
while (curNode1) {
pre = newList;
p = newList->next;
xi = curNode1->xi * curNode2->xi; //运算
zhi = curNode1->zhi + curNode2->zhi; //运算
Node* newNode = (List*)malloc(sizeof(struct List)); //创建新节点
newNode->xi = xi;
newNode->zhi = zhi;
newNode->next = NULL;
while (p != NULL&&p->zhi > zhi ){//移动指针到合适的位置
pre = pre->next;
p = p->next;
}
if (p != NULL && p->zhi == zhi) {
p->xi += xi;
if (p->xi == 0) {
pre->next = p->next;
}
}
else {
newNode->next = p;
pre->next = newNode;
}
curNode1 = curNode1->next;
}
curNode2 = curNode2->next;//判断的条件是curNode2,所以不要忘了后面指针的移动:
}
while (curNode2) {
curNode1 = list1->next;
判断的条件是curNode2,所以不要忘了后面指针的移动:
curNode2 = curNode2->next;
每次进行运算都是用list2的一个结点依次与list1所有的结点(第一个结点,第二个结点……)进行相乘。
每次指向list2的指针移动时,那么要运算的结点就变化了,指向list1的指针要指向list1的第一个结点
while (p != NULL&&p->zhi > zhi ){
pre = pre->next;
p = p->next;
}
当循环结束时,p指针指向的结点的指数是小于或等于我们待插入结点的,pre指针指向的结点的指数是大于待插入结点的。
所以新节点要插入到pre和p之间。
注意:判断条件的p != NULL一定要放在p->zhi > zhi之前。否则会读取错误的内存。
因为在a&&b判断条件中,如果a是假,那么就不会运算b是真还是假。
if (p != NULL && p->zhi == zhi) {
p->xi += xi;
if (p->xi == 0) {//在这里我们要注意运算结果为零的情况。
pre->next = p->next;//删除p指向的结点
}
}
else {
newNode->next = p;
pre->next = newNode;
}
if这段代码是当p指向的结点的指数值等于待插入结点时进行的操作。
在这里我们要注意运算结果为零的情况。因为我们是直接把待插入结点的系数加到p指向的结点的,如果运算结果是0,那么直接删除p指向的结点。
else就是正常的情况。
不要忘了移动指针:
curNode1 = curNode1->next;
如果还是没明白的话,可以看这个: