数据结构 线性表(二) 多项式加法

数据结构(二)

学习数据结构与算法过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。

—— 多项式加法 ——

1.题目描述

我们经常遇到两多项式相加的情况,在这里,我们就需要用程序来模拟实现把两个多项式相加到一起。首先,我们会有两个多项式,每个多项式是独立的一行,每个多项式由系数、幂数这样的多个整数对来表示。

如多项式2x20- x17+ 5x9- 7x7+ 16x5+ 10x4 + 22x2- 15

对应的表达式为:2 20 -1 17 5 9 - 7 7 16 5 10 4 22 2 -15 0。

为了标记每行多项式的结束,在表达式后面加上了一个幂数为负数的整数对。
同时输入表达式的幂数大小顺序是随机的。 我们需要做的就是把所给的两个多项式加起来。

原题目北京大学MOOC—数据结构—线性表练习题1

1.1输入

输入包括多行。 第一行整数n,表示有多少组的多项式需要求和。(1 < n < 100)下面为2n行整数,每一行都是一个多项式的表达式。表示n组需要相加的多项式。 每行长度小于300。

1.2输出

输出包括n行,每行为1组多项式相加的结果。 在每一行的输出结果中,多项式的每一项用“[x y]”形式的字符串表示,x是该项的系数、y是该项的幂数。要求按照每一项的幂从高到低排列,即先输出幂数高的项、再输出幂数低的项。 系数为零的项不要输出。

1.3样例输入和输出

样例输入

 2
 -1 17 2 20 5 9 -7 7 10 4 22 2 -15 0 16 5 0 -1 
 2 19 7 7 3 17 4 4 15 10 -10 5 13 2 -7 0 8 -8
 -1 17 2 23 22 2 6 8 -4 7 -18 0 1 5 21 4 0 -1 
 12 7 -7 5 3 17 23 4 15 10 -10 5 13 5 2 19 9 -7 

样例输出

[ 2 20 ] [ 2 19 ] [ 2 17 ] [ 15 10 ] [ 5 9 ] [ 6 5 ] [ 14 4 ] [ 35 2 ] [ -22 0 ] 
[ 2 23 ] [ 2 19 ] [ 2 17 ] [ 15 10 ] [ 6 8 ] [ 8 7 ] [ -3 5 ] [ 44 4 ] [ 22 2 ] [ -18 0 ]
1.4提示

第一组样例数据的第二行末尾的8 -8,因为幂次-8为负数,所以这一行数据结束,8 -8不要参与计算。

2.代码实现

c

#include <stdio.h>
#include <stdlib.h>
//定义节点结构体
typedef struct polynomial
{
    int coe;//系数
    int index;//指数
    struct polynomial*next;//指向写一个节点的指针
}pol;
//创建头节点
pol*create()
{
    pol*head=NULL;
    head=(pol*)malloc(sizeof(pol));
    head->next=NULL;
    return head;
}
//按大小插入节点
void insert(pol*head,int coe_insert,int index_insert)
{
    pol*t=(pol*)malloc(sizeof(pol));
    pol*n=head->next,*m=head;
    //插入第一个节点的操作
    if(head->next==NULL)
    {
        head->next=t;
        t->next=NULL;
        t->coe=coe_insert;
        t->index=index_insert;
    }
    //插入其余节点的操作
    else
        while(1)
        {
            //当插入节点的指数比当前指针指向的节点的指数小或者已无后续节点时
            if(n->next==NULL&&n->index>index_insert)
            {
                n->next=t;
                t->next=NULL;
                t->coe=coe_insert;
                t->index=index_insert;
                break;
            }
            if(n->index<index_insert)
            {
                m->next=t;
                t->next=n;
                t->coe=coe_insert;
                t->index=index_insert;
                break;
            }
            //当插入节点的指数和当前指针指向的节点的指数相等(虽然题目中没有提示这种情况,但是以防万一)
            if(n->index==index_insert)
            {
                n->coe=n->coe+coe_insert;
                break;
            }
            //当插入节点的指数比当前指针指向的节点的指数大,则指针继续后延
            else
            {
                m=n;
                n=n->next;
            }

        }
}
//将2个链表比较,按照要求进行整合,我选择直接整合到第一个链表中
void compare(pol*headA,pol*headB)
{
    pol*n=headA,*x,*m=headB->next;
    //具体比较和插入的逻辑大家可以看一下
    while(1)
    {
        x=m;
        if(m==NULL)
            break;
        else if(n->index==m->index)
        {
            n->coe=n->coe+m->coe;
            m=m->next;
            continue;
        }
        else if(n->next->index<m->index||n->next==NULL)
        {
            m=m->next;
            x->next=n->next;
            n->next=x;
            continue;
        }
        else
            n=n->next;
    }
}
//输出第一个链表,当系数为0时,自动跳过
void output(pol*head)
{
    pol*y=head->next;
    while(1)
    {
        if(y ->coe == 0)
           y = y ->next;
        if(y==NULL)
            break;
        printf("[ %d %d ] ",y->coe,y->index);
        y=y->next;
    }
    printf("\n");
}
int main()
{
    int num;
    scanf("%d",&num);
    for(int i=0;i<num;i++)
    {
        pol*headA=NULL;
        pol*headB=NULL;
        headA=create();
        headB=create();
        while(1)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(b<0)
                break;
            insert(headA,a,b);
        }
        while(1)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(b<0)
                break;
            insert(headB,a,b);
        }
        compare(headA,headB);
        output(headA);
    }
    return 0;
}

3.代码说明

其实不难发现,上述代码不仅浪费了很多空间(第二个链表的空间)而且运行起来应该会很慢,容错率极低,所以我们经过简化和修改,并使用C++进行了第二版修改,如下:

c++

# include<iostream>
# include<algorithm> 
using namespace std;
typedef struct polynomial
{
  int coe;
  int index;
  struct polynomial * next;
}pol;
 
bool cmp(pol a,pol b)
{
    return a.index>b.index;
}
 
void creat(pol *Head,int a,int b)
{
    pol *p=new pol;
    p->coe=a;
    p->index=b;
    p->next=Head->next;
    Head->next=p;
}
pol *insert(pol *Head,int b)
{
    pol *p=Head->next;
    while(p&&p->index!=b)
    {
        p=p->next;
    }
    return p;
}
 
void compare(pol *Head)
{
    pol *p,*q;
    int ta,tb;
    for(p=Head->next; p!=NULL; p=p->next)
      for(q=Head->next; q->next!=NULL; q=q->next)
      {
        if(q->index<q->next->index)
        {
            ta=q->coe;
            tb=q->index;
            q->coe=q->next->coe;
            q->index=q->next->index;
            q->next->coe=ta;
            q->next->index=tb;
        }
 
      }
 
}
int main(void)
{
    pol *Head=NULL, *p, *q;
    int n,t,a,b,i;
    cin>>n;
    for(i=0; i<n;i++)
    {
        Head new pol;
        Head->next=NULL;
        t=1;
        while(t<=2)
        {
            while(cin>>a>>b)
            {
                if(b<0)
                break;
                if((p=insert(Head, b))!=NULL)
                {
                    p->coe+=a;
                }
                else
                creat(Head,a,b); 
            }
            t++;
        }
        compare(Head);
        p=Head->next;
        while(p!=NULL)
        {
            if(p->coe==0)
            {
                p=p->next;
                continue;
            }
            cout<<"[ "<<p->coe<<" "<<p->index<<" ]"<<" ";
            p=p->next;
        }
        cout<<endl;
        p=Head->next;
        while(!p)
        {
            q=p;
            p=p->next;
            delete q;
        }
    }
    return 0;
}

当然还有一种更简便的办法,但是涉及到c++的map函数,大家可以直接百度一下。

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

推荐阅读更多精彩内容