PAT 一元多项式的乘法和加法

#include <stdio.h>
#include <stdlib.h>

struct Data
{
    int x;
    int y;
    struct Data *Next;
}data;
typedef struct Data *List;

void Attach(List *rear,int x,int y)
{
    List p;
    p=(List)malloc(sizeof(data));
    p->x=x;
    p->y=y;
    p->Next=(*rear)->Next;                //rear的下一个不一定是NULL
    (*rear)->Next=p;
    (*rear)=p;
}

List read()
{
    int n,x,y;
    List p,front,rear;
    
    p=(List)malloc(sizeof(data));
    p->Next=NULL;
    rear=p;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d %d",&x,&y);
        Attach(&rear,x,y);
    }
    
    front=p;
    p=p->Next;
    free(front);
    
    return p;
}

List add(List L1,List L2)
{
    List t1,t2,p,front,rear;
    
    t1=L1;
    t2=L2;
    rear=(List)malloc(sizeof(data));
    rear->Next=NULL;
    front=rear;
    
    while(t1 && t2)
    {
        if(t1->y>t2->y )
        {
            Attach(&rear,t1->x,t1->y );
            t1=t1->Next;
        }
        else if(t1->y<t2->y)
        {
            Attach(&rear,t2->x,t2->y );
            t2=t2->Next;
        }
        else
        {
            if(t1->x+t2->x==0)
            {
                t1=t1->Next;
                t2=t2->Next;
            }
            else
            {
                Attach(&rear,t1->x+t2->x,t1->y);
                t1=t1->Next;
                t2=t2->Next;
            }
        }
    }
    while(t1)
    {
        Attach(&rear,t1->x,t1->y );
        t1=t1->Next;
    }
    while(t2)
    {
        Attach(&rear,t2->x,t2->y );
        t2=t2->Next;
    }
    
    p=front;
    front=front->Next;
    free(p);
    
    return front;
}

List multiply(List L1,List L2)
{
    int x,y;
    List t1,t2,t,rear,front;
    
    if(!L1 || !L2) return NULL;
    
    t1=L1;
    t2=L2;
    front=(List)malloc(sizeof(data));
    front->Next=NULL;
    rear=front;
    while(t2)
    {
        Attach(&rear,t1->x*t2->x,t1->y+t2->y);
        t2=t2->Next;
    }
    t1=t1->Next;
    
    while(t1)
    {
        rear=front;
        t2=L2;
        while(t2)
        {
            x=t1->x*t2->x;
            y=t1->y+t2->y;
            while(rear->Next && rear->Next->y>y)
            {
                rear=rear->Next;
            }
            if(rear->Next &&rear->Next->y ==y)                 //需要先判断rear下一个是否为NULL
            {
                if(rear->Next->x+x==0) 
                {
                    rear->Next->x=0;   
                    rear->Next->y=0;  
                }
                else
                {
                    rear->Next->x+=x;
                }
            }
            else
            {
                t=(List)malloc(sizeof(data));
                t->x=x;
                t->y=y;
                t->Next=rear->Next;
                rear->Next=t;
                rear=rear->Next;
            }
            t2=t2->Next;
        }
        t1=t1->Next;
    }
    t=front;          //为什么不能换一下使用t作为头节点,因为t在上面已经用来当作malloc的临时结点 
    front=front->Next;
    free(t);
    
    return front;
}

void print(List L)
{
    if(!L)  printf("0 0");
    
    while(L)
    {
        printf("%d %d",L->x,L->y);
        L=L->Next;
        if(!L==NULL)
        {
            printf(" ");
         } 
    }
    printf("\n");
}

int main(void)
{
    List p1,p2,p3,p4,p5;
    
    p1=read();
    p2=read();
    p3=multiply(p1,p2);
    print(p3);
    p4=add(p1,p2);
    print(p4);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值