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

本文详细解析了一元多项式的乘法与加法运算过程,采用链表数据结构实现算法,包括读取多项式、相加及相乘的函数设计,并提供完整代码示例。

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

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

题目描述:

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

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

这道题要求我们设计两个函数,一个用来计算两个一元多项式的乘积,另一个用来计算两个一元多项式的和。一元多项式指的是只有一个变量 x 的多项式,例如 3x^2 + 5x - 2。 我们可以先定义一个结构体,来表示一元多项式中的每一项: ```c typedef struct { int coef; // 系数 int exp; // 指数 } PolyItem; ``` 然后,我们可以设计一个函数 `multiply`,用来计算两个一元多项式的乘积。该函数的输入参数为两个数组 `p1` 和 `p2`,分别表示两个一元多项式;输出参数为一个数组 `result`,表示两个多项式的乘积。 函数的主要思路是:对于第一个多项式中的每一项,都第二个多项式中的每一项相乘,然后把乘积相加得到结果。具体实现可以参考如下代码: ```c void multiply(int n1, PolyItem p1[], int n2, PolyItem p2[], PolyItem result[]) { int i, j, k; k = 0; // 记录结果数组中已经添加了多少项 for (i = 0; i < n1; i++) { for (j = 0; j < n2; j++) { result[k].coef = p1[i].coef * p2[j].coef; // 系数相乘 result[k].exp = p1[i].exp + p2[j].exp; // 指数相加 k++; } } } ``` 接着,我们可以设计一个函数 `add`,用来计算两个一元多项式的和。该函数的输入参数和输出参数 `multiply` 函数相同。 函数的主要思路是:对于两个多项式中的每一项,找到它们的指数相同的项,将它们的系数相加,得到结果。具体实现可以参考如下代码: ```c void add(int n1, PolyItem p1[], int n2, PolyItem p2[], PolyItem result[]) { int i, j, k; i = j = k = 0; // i、j 分别记录 p1、p2 数组中已经处理了多少项,k 记录结果数组中已经添加了多少项 while (i < n1 && j < n2) { if (p1[i].exp > p2[j].exp) { // p1 中当前项的指数较大 result[k++] = p1[i++]; } else if (p1[i].exp < p2[j].exp) { // p2 中当前项的指数较大 result[k++] = p2[j++]; } else { // 指数相同 if (p1[i].coef + p2[j].coef != 0) { // 系数相加不为 0 result[k].coef = p1[i].coef + p2[j].coef; result[k].exp = p1[i].exp; k++; } i++; j++; } } while (i < n1) { // 将 p1 中剩余的项添加到结果数组中 result[k++] = p1[i++]; } while (j < n2) { // 将 p2 中剩余的项添加到结果数组中 result[k++] = p2[j++]; } } ``` 这样,我们就完成了两个函数的设计。下面是完整的代码实现:
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值