PTA:7-1 一元多项式的乘法与加法运算

这篇文章描述了一道编程题,要求设计函数计算两个一元多项式的乘积和和。输入和输出格式已给定,涉及多项式非零项的系数和指数。代码使用链表结构,通过插入、乘法和加法函数实现,需要注意头节点处理和同类项合并。题目对时间和空间效率有一定要求。
摘要由CSDN通过智能技术生成

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

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

输入格式:

输入分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

代码长度限制                                16 KB

时间限制                                        200 ms

内存限制                                        64 MB

这道题的逻辑并不复杂,但是构想出他的整个的运行过程要考虑各种情况,导致在编程的时候浪费了大量的时间。

使用链表的方式比较灵活,但是要考虑头节点问题,这个问题搞不定,输出的结果可能就千奇百怪了。

编写过程中可以使用printf来调试程序

参考代码:

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

typedef int ElementType;
typedef struct LNode *List;

struct LNode {
    ElementType coe;//系数
    ElementType exp;//指数
    List Next;//下一个节点
};

void Insert(List L, ElementType coe, ElementType exp);//插入
List Multi(List p1, List p2);//乘法
List Plus(List p1, List p2);//加法
int compare(List p1, List p2);//比较系数大小

int main() {
    List p1, p2;
    List p;
    int num1, num2, coe, exp;
    int i;
    p1 = (List) malloc(sizeof(struct LNode));
    p2 = (List) malloc(sizeof(struct LNode));
    p1->Next = NULL;
    p2->Next = NULL;

    scanf("%d", &num1);
    for (i = 0; i < num1; i++) {
        scanf("%d %d", &coe, &exp);
        Insert(p1, coe, exp);
    }
    scanf("%d", &num2);
    for (i = 0; i < num2; i++) {
        scanf("%d %d", &coe, &exp);
        Insert(p2, coe, exp);
    }
    //乘法运算
    p = Multi(p1->Next, p2->Next);
    while (p) {
        if (p->Next != NULL) {
            printf("%d %d ", p->coe, p->exp);//非最后一个节点,不换行打印,后接空格
        } else {
            printf("%d %d\n", p->coe, p->exp);//最后一个节点,换行打印
        }
        p = p->Next;
    }
    //加法运算
    p = Plus(p1->Next, p2->Next);
    if (p) {
        while (p) {
            if (p->Next != NULL) {
                printf("%d %d ", p->coe, p->exp);
            } else {
                printf("%d %d\n", p->coe, p->exp);
            }
            p = p->Next;
        }
    } else {//防止出现p1,p2抵消为零的情况
        printf("0 0\n");
    }
    return 0;
}

/**
 * 向链表中添加元素
 * @param L 需要添加的链表
 * @param coefficient 系数
 * @param exponent 指数
 */
void Insert(List L, ElementType coe, ElementType exp) {
    List s, p;
    p = L;

    while (p->Next)//找到最后一个节点
        p = p->Next;

    s = (List) malloc(sizeof(struct LNode));
    s->Next = NULL;
    s->coe = coe;
    s->exp = exp;

    p->Next = s;
}

/**
 * 两个多项式相乘
 * @param p1 代表多项式1的链表
 * @param p2 代表多项式2的链表
 * @return p 相乘后生成的新链表
 */
List Multi(List p1, List p2) {
    List p, p1a, p2a, s;
    int flag = 1;
    p = (List) malloc(sizeof(struct LNode));
    p->Next = NULL;
    p1a = p1;

    while (p1a) {
        p2a = p2;//确保p1多项式中的每一项可以与p2多项式中的每一项分别相乘
        s = (List) malloc(sizeof(struct LNode));
        s->Next = NULL;

        while (p2a) {//与p2多项式中的每一项分别相乘
            Insert(s, p1a->coe * p2a->coe, p1a->exp + p2a->exp);
            p2a = p2a->Next;
        }
        s = s->Next;

        if (flag == 1) {
            p = p->Next;
            /*
             * 如果是p1第一项与p2每一项相乘,那么先将链表p向后移一位,将头结点屏蔽
             * 因为默认初始化的P1头结点有默认的exp = 0,coe = 0,这两个数据是多余的
             * 如果不后移,那么头结点默认的数值0将会一直尾随整个乘法运算,导致最后的结果后面多两个0 0
             */
            flag = 0;

        }
        p = Plus(p, s);//相加,确保同类项合并
        p1a = p1a->Next;
        free(s);
    }

    return p;
}

/**
 * 比较两多项式指数大小
 * @param p1 代表多项式1的链表
 * @param p2 代表多项式2的链表
 * @return 返回值为0时表示两指数相同,可以进行加法运算
 */
int compare(List p1, List p2) {
    if (p1->exp > p2->exp)
        return 1;//p1指数大
    else if (p1->exp < p2->exp)
        return -1;//p1指数小
    else
        return 0;//指数相同
}

/**
 * 两个多项式相加
 * @param p1 代表多项式1的链表
 * @param p2 代表多项式2的链表
 * @return p 相加后生成的新链表
 */
List Plus(List p1, List p2) {
    List p, p1a, p2a;
    int temp;
    p = (List) malloc(sizeof(struct LNode));
    p->Next = NULL;
    p1a = p1;
    p2a = p2;

    while (p1a && p2a) {
        temp = compare(p1a, p2a);
        //判断指数大小,同指数才可以运算
        switch (temp) {
            case 1:
                //当前p1a的指数大,将当前p1a的数据放入新链表
                Insert(p, p1a->coe, p1a->exp);
                p1a = p1a->Next;//p1a向后移动,p2a不改变
                break;
            case -1:
                //当前p2a的指数大,将当前p2a的数据放入新链表
                Insert(p, p2a->coe, p2a->exp);
                p2a = p2a->Next;//p2a向后移动,p1a不改变
                break;
            case 0:
                //指数相同,进行运算
                if ((p1a->coe + p2a->coe) == 0) {
                    //系数为0,数据不放入新链表,直接将p1a和p2a后移
                    p1a = p1a->Next;
                    p2a = p2a->Next;
                } else {
                    //数据放入新链表,p1a和p2a后移
                    Insert(p, p1a->coe + p2a->coe, p2a->exp);
                    p1a = p1a->Next;
                    p2a = p2a->Next;
                }
                break;
            default:
                break;
        }
    }
    while (p1a) {
        //p1a的项数多,将剩余项放入链表
        Insert(p, p1a->coe, p1a->exp);
        p1a = p1a->Next;
    }
    while (p2a) {
        //p2a的项数多,将剩余项放入链表
        Insert(p, p2a->coe, p2a->exp);
        p2a = p2a->Next;
    }
    p = p->Next;
    return p;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

追上

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

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

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

打赏作者

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

抵扣说明:

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

余额充值