浙大数据结构题目集:一元多项式的乘法与加法运算

一元多项式的乘法与加法运算

这道题其实直接根据老师的思路就可以了,老师的思路非常清晰,而且代码也很规范,走一遍老师的代码可以学到很多东西。

题目描述:

输入格式:
输入分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

思路:
程序框架直接看主函数。采用链表来实现,编程稍微有点复杂。
Add函数,创造一个新链表用来储存结果,把相加以后的节点插入这个链表。用两个指针遍历两个多项式链表,指数较大的直接插入新表,指数相等则系数相加以后再插入新表。
mult函数,创造一个新链表来储存结果,先将p1的第一项乘以p2,存到新链表里。然后依次从第二项开始每一项都乘一次p2,将得到的结果逐项插入到新链表里。

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

typedef struct PolyNode* Polynomial;
struct PolyNode
{
    int coef;
    int expo;
    Polynomial link;
};

void Attach(int c, int e, Polynomial *pRear) //加在新链表尾部
{
    Polynomial p;
    p = (Polynomial)malloc(sizeof(struct PolyNode));
    p->coef = c;
    p->expo = e;
    p->link = NULL;
    (*pRear)->link = p; //pRear是指针的指针,要先进行取值运算得到指针rear,再修改Link
    *pRear = p;
}

Polynomial ReadPoly() //读入多项式
{
    Polynomial p, rear, t;
    int c, e;

    p = (Polynomial)malloc(sizeof(struct PolyNode)); //防止Attach函数遇到链表为空的情况,加上一个空节点
    p->link = NULL;
    rear = p;

    int n;
    scanf("%d", &n);

    for(int i = 0; i < n; i++)
    {
        scanf("%d %d", &c, &e);
        Attach(c, e, &rear);
    }

    t = p;
    p = p->link;
    free(t);

    return p;
}


Polynomial Add(Polynomial p1, Polynomial p2)
{
    Polynomial t1, t2, p, rear, temp;

    p = (Polynomial)malloc(sizeof(struct PolyNode)); //空节点,储存相加以后的链表
    p->link = NULL;
    rear = p;

    t1 = p1; t2 = p2;
    int sum;
    while(t1&&t2)
    {
        if(t1->expo == t2->expo){
            sum = t1->coef + t2->coef;
            if(sum)
                Attach(t1->coef + t2->coef, t1->expo, &rear);
            t1 = t1->link;
            t2 = t2->link;
        }else if(t1->expo > t2->expo){
            Attach(t1->coef, t1->expo, &rear);
            t1 = t1->link;
        }else{
            Attach(t2->coef, t2->expo, &rear);
            t2 = t2->link;
        }
    }

    while(t1){
        Attach(t1->coef, t1->expo, &rear);
        t1 = t1->link;
    }

    while(t2){
        Attach(t2->coef, t2->expo, &rear);
        t2 = t2->link;
    }

    rear->link = NULL;
    temp = p;
    p = p->link;
    free(temp);

    return p;
}

Polynomial Mult(Polynomial p1, Polynomial p2)
{
    Polynomial p, rear, t1, t2, t;
    int c, e;

    if(!p1 || !p2) return NULL; //特殊情况

    p = (Polynomial)malloc(sizeof(struct PolyNode)); //空节点,储存相加以后的链表
    p->link = NULL;
    rear = p;

    t1 = p1; t2 = p2;
    while(t2){ //先用p1第一项乘p2,得到一个p,然后再后续插入相乘结果
        Attach(t1->coef*t2->coef, t1->expo + t2->expo, &rear);
        t2 = t2->link;
    }
    t1 = t1->link;

    while(t1){
        t2 = p2; rear = p; //rear从头开始遍历
        while(t2){
            c = t1->coef * t2->coef;
            e = t1->expo + t2->expo;
            while(rear->link && rear->link->expo > e)
                rear = rear->link;
			if(rear->link && rear->link->expo==e){	//指数相等的情况
				if(rear->link->coef+c) //系数相加不为零
					rear->link->coef+=c;
				else{ //系数相加为0,将这个节点删除
					t = rear->link;
					rear->link = t->link;
                    free(t);
                }
            }else{ //指数不相等,即rear后面那一项的指数要小,所以插入到rear的后面
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef = c; t->expo = e;
                t->link = rear->link;
                rear->link = t;
                rear = rear->link;
            }
            t2 = t2->link;
        }
        t1 = t1->link;
    }

    rear = p; p = p->link; free(rear);

    return p;
}



void PrintPoly(Polynomial p)
{
    if(!p) {printf("0 0\n"); return;} //特殊情况

    int flag = 0;
    while(p)
    {
        if(!flag)
            flag = 1;
        else
            printf(" ");
        printf("%d %d", p->coef, p->expo);
        p = p->link;
    }
    printf("\n");
}


int main()
{
    Polynomial p1, p2, pp, ps;

    p1 = ReadPoly();
    p2 = ReadPoly();
    pp = Mult(p1, p2);
    PrintPoly(pp);
    ps = Add(p1, p2);
    PrintPoly(ps);

    return 0;
}

已通过测试,可以直接复制查看结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值