七、一元多项式相乘

七、一元多项式相乘

题目描述

要求采用链表形式,求两个一元多项式的乘积: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秒1024KB0
测试用例 2<0,0>,
<1,20>,<-8,40>,
<0,0>,1秒1024KB0
测试用例 3<1,20>,<-8,40>,
<0,0>,
<0,0>,1秒1024KB0
测试用例 4<-1,0>,<1,1>,
<1,0>,<1,1>,
<-1,0>,<1,2>,1秒1024KB0
测试用例 5<5,0>,<10,1>,
<2,0>,< 3,1>,<4,2>,<5,3>,
<10,0>,<35,1>,<50,2>,<65,3>,<50,4>,1秒1024KB0

解题思路

乘法和加法不一样,乘法必须对多项式中的每一项都进行相乘。

因为题目要以指数递增的顺序输出乘积,在运算时还需要调整多项式之间的位置。

用三个指针 p1p2p3,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;
}
  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值