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

题目

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

示例

输入

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

输出

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

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

题目分析

输入分析

  • 第一个数字是多项式项数
  • 后面的数字,分别为系数和指数
  • 指数是递降的

使用链表,结点定义如下

typedef struct ListNode* poly;
struct ListNode{
    int zhi;  //指数
    int xi;   //系数
    poly next;  //指向下一个结点
};

结点插入

用作读取、加法和乘法的结点插入,解决链表问题的常规操作。

poly Attach(int xi, int zhi, poly p){
    poly temp = malloc(sizeof(poly));
    temp->xi = xi;
    temp->zhi = zhi;
    temp->next = NULL;
    p->next = temp;
    return p->next;
}

读取输入

使用变量num记录多项式项数,循环调用Attach函数,将新结点插入。

poly ReadPoly(){
    poly p = malloc(sizeof(poly));
    poly temp = p;
    int num;
    scanf("%d", &num);
    int x, y;
    for (int i = 0; i < num; i++){
        scanf("%d %d", &x, &y);
        temp = Attach(x, y, temp);
    }
    return p->next;
}

加法的实现

按顺序遍历两个多项式链表ab,使用结点restemp储存结果。
a->zhi > b->zhi,将a储存为新节点;
a->zhi = b->zhi,将ab的系数加和,若系数不为0,则储存为新结点;
a->zhi < b->zhi,将b储存为新节点。

poly add(poly a, poly b){
    poly res, temp;
    res = malloc(sizeof(poly));
    temp = res;
    
    while (a != NULL && b != NULL){
        if (a->zhi > b->zhi){
            temp = Attach(a->xi, a->zhi, temp);
            a = a->next;
        }else if (a->zhi == b->zhi){
            int xi = a->xi + b->xi;
            if (xi != 0){
                temp = Attach(a->xi + b->xi, a->zhi, temp);
            }
            a = a->next;
            b = b->next;
        }else{
            temp = Attach(b->xi, b->zhi, temp);
            b = b->next;
        }
    }
    
    if (a != NULL){
        temp->next = a;
    }
    if (b != NULL){
        temp->next = b;
    }
    
    return res->next;
}

乘法的实现

乘法的实现是本题的难点。
首先判断是否有空链表,若有,则乘法的结果必然是空链表。
没有空链表的情况,则采用化乘法为加法的方式,用p1去逐项乘以p2,再将得到的结果利用add函数加和即可。

poly mul(poly a, poly b){
    if (a == NULL || b == NULL) return NULL;
    
    poly res, temp, p1, p2;
    p1 = a;
    p2 = b;
    res = malloc(sizeof(poly));
    temp = res;
    
    while (p2 != NULL){
        temp = Attach(p1->xi * p2->xi, p1->zhi + p2->zhi, temp);
        p2 = p2->next;
    }
    p1 = p1->next;
    while (p1 != NULL){
        p2 = b;
        temp = res;
        while (p2 != NULL){
            int xi, zhi;
            xi = p1->xi * p2->xi;
            zhi = p1->zhi + p2->zhi;
            while (temp->next != NULL && temp->next->zhi > zhi){
                temp = temp->next;
            }
            if (temp->next != NULL && temp->next->zhi == zhi){
                temp->next->xi += xi;
                if (temp->next->xi == 0){
                    temp->next = temp->next->next;
                }
            }else {
                poly t = malloc(sizeof(poly));
                t->xi = xi;
                t->zhi = zhi;
                t->next = temp->next;
                temp->next = t;
                temp = temp->next;
            }
            p2 = p2->next;
        }
        p1 = p1->next;
    }
    return res->next;
}

输出函数

输出要求,输出结尾不可以有多余的空格,需要特殊处理
利用一个标记变量flag,将其初始值设为0,循环开始后,将其置为1,之后的每次循环都输出一个空格,直到输出结束。

void PrintPoly(poly p){
    int flag = 0;
    
    if (p == NULL) printf("0 0");
    
    while (p != NULL){
        if (flag == 0) flag = 1;
        else {
            printf(" ");
        }
        printf("%d %d", p->xi, p->zhi);
        p = p->next;
    }
    printf("\n");
}

题目解答

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

typedef struct ListNode* poly;
struct ListNode{
    int zhi;  //指数
    int xi;   //系数
    poly next;  //指向下一个结点
};

poly Attach(int xi, int zhi, poly p){
    poly temp = malloc(sizeof(poly));
    temp->xi = xi;
    temp->zhi = zhi;
    temp->next = NULL;
    p->next = temp;
    return p->next;
}

poly ReadPoly(){
    poly p = malloc(sizeof(poly));
    poly temp = p;
    int num;
    scanf("%d", &num);
    int x, y;
    for (int i = 0; i < num; i++){
        scanf("%d %d", &x, &y);
        temp = Attach(x, y, temp);
    }
    return p->next;
}

void PrintPoly(poly p){
    int flag = 0;
    
    if (p == NULL) printf("0 0");
    
    while (p != NULL){
        if (flag == 0) flag = 1;
        else {
            printf(" ");
        }
        printf("%d %d", p->xi, p->zhi);
        p = p->next;
    }
    printf("\n");
}

poly add(poly a, poly b){
    poly res, temp;
    res = malloc(sizeof(poly));
    temp = res;
    
    while (a != NULL && b != NULL){
        if (a->zhi > b->zhi){
            temp = Attach(a->xi, a->zhi, temp);
            a = a->next;
        }else if (a->zhi == b->zhi){
            int xi = a->xi + b->xi;
            if (xi != 0){
                temp = Attach(a->xi + b->xi, a->zhi, temp);
            }
            a = a->next;
            b = b->next;
        }else{
            temp = Attach(b->xi, b->zhi, temp);
            b = b->next;
        }
    }
    
    if (a != NULL){
        temp->next = a;
    }
    if (b != NULL){
        temp->next = b;
    }
    
    return res->next;
}

poly mul(poly a, poly b){
    if (a == NULL || b == NULL) return NULL;
    
    poly res, temp, p1, p2;
    p1 = a;
    p2 = b;
    res = malloc(sizeof(poly));
    temp = res;
    
    while (p2 != NULL){
        temp = Attach(p1->xi * p2->xi, p1->zhi + p2->zhi, temp);
        p2 = p2->next;
    }
    p1 = p1->next;
    while (p1 != NULL){
        p2 = b;
        temp = res;
        while (p2 != NULL){
            int xi, zhi;
            xi = p1->xi * p2->xi;
            zhi = p1->zhi + p2->zhi;
            while (temp->next != NULL && temp->next->zhi > zhi){
                temp = temp->next;
            }
            if (temp->next != NULL && temp->next->zhi == zhi){
                temp->next->xi += xi;
                if (temp->next->xi == 0){
                    temp->next = temp->next->next;
                }
            }else {
                poly t = malloc(sizeof(poly));
                t->xi = xi;
                t->zhi = zhi;
                t->next = temp->next;
                temp->next = t;
                temp = temp->next;
            }
            p2 = p2->next;
        }
        p1 = p1->next;
    }
    return res->next;
}

int main(){
    poly a, b, res_add, res_mul;
    
    a = ReadPoly();
    b = ReadPoly();
    
    res_mul = mul(a, b);
    PrintPoly(res_mul);
    
    res_add = add(a, b);
    PrintPoly(res_add);
    
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容