七、一元多项式相乘
题目描述
要求采用链表形式,求两个一元多项式的乘积:h3 = h1*h2。函数原型为:void multiplication( NODE * h1, NODE * h2, NODE * h3 )。
输入:
输入数据为两行,分别表示两个一元多项式。每个一元多项式以指数递增的顺序输入多项式各项的系数(整数)、指数(整数)。
例如:1+2x+x2表示为:<1,0>,<2,1>,<1,2>,
输出:
以指数递增的顺序输出乘积: <系数,指数>,<系数,指数>,<系数,指数>,
零多项式的输出格式为:<0,0>,
说明:本题目有预设代码,只要提交你编写的函数即可。
预设代码:
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int coef, exp;
struct node *next;
} NODE;
void multiplication( NODE *, NODE * , NODE * );
void input( NODE * );
void output( NODE * );
void input( NODE * head )
{
int flag, sign, sum, x;
char c;
NODE * p = head;
while ( (c=getchar()) !='\n' )
{
if ( c == '<' )
{ sum = 0;
sign = 1;
flag = 1;
}
else if ( c =='-' )
sign = -1;
else if( c >='0'&& c <='9' )
{ sum = sum*10 + c - '0';
}
else if ( c == ',' )
{ if ( flag == 1 )
{ x = sign * sum;
sum = 0;
flag = 2;
sign = 1;
}
}
else if ( c == '>' )
{ p->next = ( NODE * ) malloc( sizeof(NODE) );
p->next->coef = x;
p->next->exp = sign * sum;
p = p->next;
p->next = NULL;
flag = 0;
}
}
}
void output( NODE * head )
{
while ( head->next != NULL )
{ head = head->next;
printf("<%d,%d>,", head->coef, head->exp );
}
printf("\n");
}
int main()
{
NODE * head1, * head2, * head3;
head1 = ( NODE * ) malloc( sizeof(NODE) );
input( head1 );
head2 = ( NODE * ) malloc( sizeof(NODE) );
input( head2 );
head3 = ( NODE * ) malloc( sizeof(NODE) );
head3->next = NULL;
multiplication( head1, head2, head3 );
output( head3 );
return 0;
}
/**************************************
void multiplication( NODE *, NODE * , NODE * )
{
This function is wating for you.
}
***************************************/
/* PRESET CODE END - NEVER TOUCH CODE ABOVE */
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | <1,0>,<2,1>,<1,2>, <1,0>,<1,1>, | <1,0>,< 3,1>,< 3,2>,<1,3>, | 1秒 | 1024KB | 0 |
测试用例 2 | <0,0>, <1,20>,<-8,40>, | <0,0>, | 1秒 | 1024KB | 0 |
测试用例 3 | <1,20>,<-8,40>, <0,0>, | <0,0>, | 1秒 | 1024KB | 0 |
测试用例 4 | <-1,0>,<1,1>, <1,0>,<1,1>, | <-1,0>,<1,2>, | 1秒 | 1024KB | 0 |
测试用例 5 | <5,0>,<10,1>, <2,0>,< 3,1>,<4,2>,<5,3>, | <10,0>,<35,1>,<50,2>,<65,3>,<50,4>, | 1秒 | 1024KB | 0 |
解题思路
乘法和加法不一样,乘法必须对多项式中的每一项都进行相乘。
因为题目要以指数递增的顺序输出乘积,在运算时还需要调整多项式之间的位置。
用三个指针 p1
、p2
、p3
,p1用于建立第一个结点,p3记录上一次的结点位置,帮助p2寻找指数对应位置的结点
对该结点的后一个结点进行判断:
- 如果该结点后续为空,建立新结点
- 若后续不为空,则比较对应指数
- 指数相等则合并节点(若系数为空则删除该结点)
- 指数较大则建立新结点插入
最后,不要忘了为零多项式建立结点进行输出。
上机代码
void multiplication(NODE *head1, NODE *head2, NODE *head3)
{
// 初始化
NODE *p1, *p2, *p3;
p1 = p2 = p3 = head3;
NODE *h1 = head1->next, *h2 = head2->next;
int coef = 0, exp = 0;
//分项相乘相加
while(h1 != NULL)
{
while(h2 != NULL)
{
coef = h1->coef * h2->coef;//处理系数
if (coef == 0)//系数为0直接进入下一次
{
h2 = h2->next;
continue;
}
exp = h1->exp + h2->exp;//处理指数
if (p1->next == NULL)//创建第一个节点
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
s->next = NULL;
p1->next = s;
}
else
{
//找到指数对应位置的结点
if(p3->next != NULL && exp > p3->next->exp)//指数大
{
p2 = p3;
while(p2->next != NULL && exp > p2->next->exp)
{
p2 = p2->next;
p3 = p2;
}
}
else//指数小
{
while(p2->next != NULL && exp > p2->next->exp)
{
p2 = p2->next;
p3 = p2;
}
}
NODE *temp = p2->next;
if(p2->next == NULL)//若该结点后为空,建立新结点
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
s->next = NULL;
p2->next = s;
}
else if(temp->exp == exp)//指数相等则合并节点
{
temp->coef += coef;
if(temp->coef == 0)//值为0,则删除节点
{
NODE *dele = temp->next;
p2->next = dele;
free(temp);
}
}
else if(temp->exp > exp)//指数大则插入新结点
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
p2->next = s;
s->next = temp;
}
}
//下一项
h2 = h2->next;
p2 = head3;
}
//一轮循环结束,h2从头开始乘以下一项
h2 = head2->next;
h1 = h1->next;
}
//处理零多项式的情况
if(head3->next == NULL)
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = 0;
s->exp = 0;
s->next = NULL;
head3->next = s;
}
return;
}