7-2 一元多项式的乘法与加法运算 (20分)

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分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<stdio.h>
#include<stdlib.h>

typedef struct expression *List;
typedef struct expression Node;

struct expression
{
    int ratio;//系数
    int index;//指数
    List Next;
};

List InPut(int num);//输入
void Delete(List L); //释放
void OutPut(List L); //输出
//----------------------------------------------
List Product(List L1,List L2);
void Attach(int r,int i,List *p);
List Add(List L1,List L2);

int main(void)
{
    int num1;
    scanf("%d",&num1);
    List L1=InPut(num1);


    int num2;
    scanf("%d",&num2);
    List L2=InPut(num2);

    List L3=Product(L1,L2);

    List L4=Add(L1,L2);

    OutPut(L3);
    OutPut(L4);

    Delete(L1);
    Delete(L2);
    Delete(L3);
    Delete(L4);

    return 0;
}
void OutPut(List L)
{
    if(!L)
        printf("0 0\n");
    else
    {
        while(L)
        {
            printf("%d %d",L->ratio,L->index);
            if(L->Next!=NULL)
                printf(" ");
            L=L->Next;
        }
        printf("\n");
    }
}


List InPut(int num)
{
    List head1=(List )malloc(sizeof(Node));
    if(head1==NULL)
        exit(EXIT_FAILURE);
    head1->index=head1->ratio=0;
    head1->Next=NULL;
    List record=head1;
    for(int i=0;i<num;i++)
    {
        if(i==0)
        {
            scanf("%d",&head1->ratio);
            scanf("%d",&head1->index);
        }
        else
        {
            List L1=(List )malloc(sizeof(Node));
            if(L1==NULL)
                exit(EXIT_FAILURE);
            scanf("%d",&L1->ratio);
            scanf("%d",&L1->index);
            L1->Next=NULL;
            record->Next=L1;
            record=L1;
        }
    }
    return head1;
}
void Delete(List L)
{
    List p=L;
    while(p!=NULL)
    {
        L=p->Next;
        free(p);
        p=L;
    }
}

自己只能写出来输入,输出与释放函数。

List Product(List L1,List L2);
void Attach(int r,int i,List *p);
List Add(List L1,List L2);

这三个函数是看另一位博主写的。
王寒寒<——可以移步去这个链接。

下面的我改了一些变量名的,基本是一样的。

List Add(List L1,List L2)
{
    List head=(List)malloc(sizeof(Node));
    head->index=0;
    head->ratio=0;
    head->Next=NULL;
    List record=head,record1=L1,record2=L2;
    while(record1&&record2)
    {
        if(record1->index>record2->index)//一的指数大,先放一
        {
            Attach(record1->ratio,record1->index,&record);
            record1=record1->Next;
        }
        else if(record1->index<record2->index)//二的指数大,先放二
        {
            Attach(record2->ratio,record2->index,&record);
            record2=record2->Next;
        }
        else//相等
        {
            int sum=record1->ratio+record2->ratio;
            if(sum)
                Attach(sum,record1->index,&record);
            record1=record1->Next;
            record2=record2->Next;
        }
    }
    //看谁还有剩,谁就接上去
    while(record1)
    {
        Attach(record1->ratio,record1->index,&record);
        record1=record1->Next;
    }
    while(record2)
    {
        Attach(record2->ratio,record2->index,&record);
        record2=record2->Next;
    }
    List t=head;
    head=head->Next;
    free(t);
    t=NULL;
    return head;
}
List Product(List L1,List L2)
{
    if(!L1||!L2)//如果有一个是空就返回空
        return NULL;
    List head=(List)malloc(sizeof(Node));//建立一个头结点
    head->index=head->ratio=0;
    head->Next=NULL;
    List record1=L1,record2=L2,record=head;//因为要移动,所以用新指针
    while(record2)//先把L1的第一项与L2全乘一遍
    {
        Attach(record2->ratio*record1->ratio,record2->index+record1->index,&record);
        record2=record2->Next;
    }
    record1=record1->Next;//L1变到第二项去
    while(record1)
    {
        record2=L2;//L2从头来了
        record=head;//head也从头来
        while(record2)//每个L1与所有的L2都计算一下
        {
            int r=record1->ratio*record2->ratio;//系数
            int i=record1->index+record2->index;//指数
            while(record->Next&&record->Next->index>i)//如果指数小,那就不用插入head中>,直到大于或等于,为什么不从record开始,因为它是头结点没有有效值,这样就可以用Next。
                record=record->Next;
            if(record->Next&&record->Next->index==i)//指数相同
            {
                record->Next->ratio+=r;//系数相加
                if(!record->Next->ratio)//系数为0
                {
                    List temp=record->Next;
                    record->Next=temp->Next;//把record指向下下个
                    free(temp);//这个没用的释放掉
                    temp=NULL;
                }
            }
            else//(指数不同,新建一个插入,位置在record->Next前面)
            {
                List temp = (List)malloc(sizeof(Node));
                temp->ratio = r;
                temp->index = i;
                //将temp插入
                temp->Next = record->Next;
                record->Next = temp;
                //record也前进
                record = temp;
            }
            record2 = record2->Next;
        }
        record1=record1->Next;
    }
    List t=head;
    head=head->Next;
    free(t);//把头释放掉
    t=NULL;
    return head;
}
void Attach(int r,int i,List *p)//我们要改变record中Next的值,所以用指针。
{
    if(r == 0)//如果系数是0
    {
        return ;
    }
    List q=(List)malloc(sizeof(Node));//新建结点保存新值,再接上
    q->ratio=r;
    q->index=i;
    q->Next=NULL;
    (*p)->Next=q;
    (*p)=q;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CCPigSnail

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值