X-man

导航

实习一 线性表及其应用 (题目:一元稀疏多项式的加法运算 )

一、需求分析

         1.输入并建立两个多项式;

         2.多项式a与b相加,建立和多项式c;

         3.输出多项式a,b,c。输出格式:比如多项式a为:A(x)=c1xe1+

    c2xe2+…+ cmxem,其中,ci和ei分别为第i项的系数和指数,且各项按

    指数的升幂排列,即0≤e1<e2<…<em。多项式b,c类似输出。

         4测试数据

         (1)(1+x+x2+x3+x4+x5)+(-x3-x4)=(1+x+x2+x5)

         (2)(x+x100)+(x100+x200)=(x+2x100+x200)

         (3)(2x+5x8-3x11)+(7-5x8+11x9)=(7+2x+11x9-3x11)

源码:https://wenku.baidu.com/view/a114cb269a89680203d8ce2f0066f5335b81671f
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int DaTatype;
typedef struct Node
{
    DaTatype xishu;
    DaTatype zhishu;
    struct Node *next;
}SLNode;
void ListInitiate(SLNode **head)                          //初始化
{
    *head=(SLNode*)malloc(sizeof(SLNode));
    (*head)->next=NULL;
}
int ListInsert(SLNode *head,DaTatype xishu,DaTatype zhishu)//插入
{
    SLNode *p,*q;
    p=head;
    while(p->next!=NULL)
    {
        if((p->next->zhishu)>zhishu)break;               //比较指数大小 
        p=p->next;                                       //链表中节点指数大,则比较链表下一个 
    }
    q=(SLNode*)malloc(sizeof(SLNode));                   //链表中节点指数小,则在该节点前插入 
    q->xishu=xishu;
    q->zhishu=zhishu;
    q->next=NULL;
    q->next=p->next;
    p->next=q;
    return 1;
}
int ListGet(SLNode *head)                                   //输出
{
    SLNode *p;
    p=head->next;
    int kaiguan=1;
    if(p==NULL)printf("0\n");                      //判断头结点为空的输出 
     while(p!=NULL)                                //判断头结点非空
    {
        if(kaiguan==1)                             //多项式第一项的输出 
        {
            if(p->zhishu==0)                       //当指数为时,只输出系数xishu
                printf("%d",p->xishu);
            else if(p->xishu==1)                    //系数为1时输出X^zhishui或x 
               {if(p->zhishu==1)printf("x");
                else  printf("x^%d",p->zhishu);
               }
            else if(p->xishu==-1)                       //系数为-1时输出-X^zhishui或-x 
               {if(p->zhishu==1)printf("-x");
                else  printf("-x^%d",p->zhishu);
               }
            else if(p->xishu>0)                          //系数大于0时 
               {if(p->zhishu==1)printf("%dx",p->xishu);
                else printf("%dx^%d",p->xishu,p->zhishu);
               }        
            else if(p->xishu<0)                             //系数为负数时,原样输出
               {if(p->zhishu==1)printf("%dx",p->xishu);
                else printf("%dx^%d",p->xishu,p->zhishu);
               }
            kaiguan=0;
        }
        else{                                              //多项式的其余项都前带符号输出 
            if(p->zhishu==0)
            {if(p->xishu!=0)
            printf("+%d",p->xishu);
            }
            else if(p->xishu==1)                           
               {if(p->zhishu==1)printf("+x");
                else  printf("+x^%d",p->zhishu);
               }
            else if(p->xishu==-1)                          
               {if(p->zhishu==1)printf("-x");
                else  printf("-x^%d",p->zhishu);
               }
            else if(p->xishu>0)                           //系数大于0时,系数前面带“+”
               {if(p->zhishu==1)printf("+%dx",p->xishu);
                else printf("+%dx^%d",p->xishu,p->zhishu);
               }            
            else if(p->xishu<0)                            //系数为负时,原样输出
               {if(p->zhishu==1)printf("%dx",p->xishu);
                else printf("%dx^%d",p->xishu,p->zhishu);
               }            
        }
        p=p->next;
    }
    printf("\n");
    return 1;
}
     /* while(p->next!=NULL)
    {
     while(p->zhishu==0)
    {
        printf("%d",p->xishu);
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }
     while(p->xishu==1&&p->zhishu==1)
    {
        printf("x");
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }
         while(p->xishu==1&&p->zhishu!=1)
    {
        printf("x^%d",p->zhishu);
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }
    while(p->xishu==-1&&p->zhishu==1)//指数不为零时系数为1时的输出
    {
        printf("-x");
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }
        while(p->xishu==-1&&p->zhishu!=1)//指数不为零时系数为1时的输出
    {
        printf("-x^%d",p->zhishu);
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }
   while(p->xishu!=1&&p->xishu!=-1&&p->zhishu!=0&&p->zhishu!=1)
    {
        printf("%dx^%d",p->xishu,p->zhishu);
        p=p->next;
        if(p==NULL&&p->xishu<0)
            return 0;
        else printf("+");
    }

        printf("%dx^%d",p->xishu,p->zhishu);
        p=p->next;
        if(p->xishu>0)
            printf("+");
    }
    printf("%dx^%d",p->xishu,p->zhishu);*/
int ListAdd(SLNode*head1,SLNode*head2,SLNode*head3)
{
    SLNode *p,*q,*s,*r;
    int n=0;
    p=head1;q=head2;s=head3;
    while(p->next!=NULL)                                     //先将a存入c中
    {
        r=(SLNode*)malloc(sizeof(SLNode));
        r->zhishu=p->next->zhishu;
        r->xishu=p->next->xishu;
        r->next=NULL;
        s->next=r;
        p=p->next;
        s=s->next;
    }
    s=head3;
    while(s->next!=NULL &&q->next!=NULL )
    {
         while(s->next!=NULL && s->next->zhishu<q->next->zhishu)//搜寻          {
         s=s->next;
         if(s->next!=NULL)n=1;
         if(n){
         if( s->next->zhishu==q->next->zhishu )
         {
             if(s->next->xishu+q->next->xishu!=0)
             {s->next->xishu=s->next->xishu+q->next->xishu;
             s=s->next;}
            else s->next=s->next->next;
           }
         else
         {
               r=(SLNode*)malloc(sizeof(SLNode));
             r->zhishu=q->next->zhishu;
              r->xishu=q->next->xishu;
            r->next=s->next;
            s->next=r;
            s=s->next;
         }//插入          
           q=q->next;
           n=0;
           }
    }
    if(q->next!=NULL&&s->next==NULL)s->next=q->next;      //剩余项的接到C链表的尾部 
    return 1;
}
int main()
{
    SLNode *head1,*head2,*head3;
    int i,n;
    int xishu,zhishu;
    ListInitiate(&head1);
    ListInitiate(&head2);
    ListInitiate(&head3);
        printf("请输入a的项数:");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("输入a的第%d项系数:",i+1);
        scanf("%d",&xishu);
        printf("输入a的第%d项指数:",i+1);
        scanf("%d",&zhishu);
        ListInsert(head1,xishu,zhishu);
    }
        printf("输入b的项数:");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("输入b的第%d项系数:",i+1);
        scanf("%d",&xishu);
        printf("输入b的第%d项指数:",i+1);
        scanf("%d",&zhishu);
        ListInsert(head2,xishu,zhishu);
    }
    ListAdd(head1,head2,head3);
    printf("输入的多项式a为:\n");
    ListGet(head1);
    printf("\n");
    printf("输入的多项式b为:\n");
    ListGet(head2);
    printf("\n");
    printf("多项式c为:\n");
    ListGet(head3);
    printf("\n");
    return 1;
}

 

                                                                          实习一 线性表及其应用

     题目:一元稀疏多项式的加法运算    实习时间:2012/9/20.10.12

 

一、需求分析

         1.输入并建立两个多项式;

         2.多项式a与b相加,建立和多项式c;

         3.输出多项式a,b,c。输出格式:比如多项式a为:A(x)=c1xe1+

    c2xe2+…+ cmxem,其中,ci和ei分别为第i项的系数和指数,且各项按

    指数的升幂排列,即0≤e1<e2<…<em。多项式b,c类似输出。

         4测试数据

         (1)(1+x+x2+x3+x4+x5)+(-x3-x4)=(1+x+x2+x5)

         (2)(x+x100)+(x100+x200)=(x+2x100+x200)

         (3)(2x+5x8-3x11)+(7-5x8+11x9)=(7+2x+11x9-3x11)        

二、设计

      1. 设计思想

        (1)存储结构

            用带头结点的单链表存储多项式。

            三个多项式链表中都只存储非零系数项。若多项式a与b中指数相

等的两项相加后,系数为零,则在和多项式c中不存储该指数项。

        (2)主要算法基本思想    

    按照链表的基本操作,初始化三个链表,在两个链表中按指数由小到大分别插入a和b的多项式(系数和指数),将多项式a的链表复制给多项式c的链表,再调用求和函数(b的链表和c的链表相加),将求和的结果插入到c的链表中(作为多项式c),最后输出多项式a,b,c三个多项式。

        【1】插入函数:设计按多项式指数的从小到大插入。从第一个元素开始判断,直到遇到比插入元素更大的指数或链表尾为止,再进行插入操作。

        【2】求和函数: 先将多项式a的链表复制给多项式c的链表,在b的链表不为空的前提下,将b中的各项的指数与c中各项的指数比较大小。

        (1)若相等,就将该项的系数相加,和不为零就将c中该项的系数替换为其和(何若为零则删除该节点)。

        (2)若b中的指数大,就在c链表该节点之前插入b项的此节点。

        (3)若b中的指数小,就一直查找到c链表尾。再将多余的b链表一起复制给c链表。

        【3】输出函数(系数为0的项已被删除):

多项式第一项若为正数,无需符号,其余项带符号输出(定义一个开关变量)

(1)    系数为a,指数b为0的项输出(a)。

(2)    系数a为1,指数b为1的项输出(x)。

(3)    系数a为1,指数b不为1的项输出(x^b)。

(4)    系数a为-1,指数b为1的项输出(-x)。

(5)    系数a为-1,指数b不为1的项输出(-x^b)。

(6)    系数a不为1或-1,指数b不为0或1的项输出(ax^b)。

      2. 设计表示

       (1)函数调用关系图

               main→ListInitiate→ListInsert→ListAdd→ListGet

       (2)函数接口规格说明

               void ListInitiate(SLNode **head)/*初始化以head为头指针的单链表*/

               int ListInsert(SLNode *head,DaTatype xishu,DaTatype zhishu) /*在单链表中按指数的由小到大顺序插入多项式的指数和系数*/

               int ListAdd(SLNode*head1,SLNode*head2,SLNode*head3)/*以head1为头指针的单链表与以head2为头指针的单链表相加等于以head3为头指针的单链表*/

               Int ListGet(SLNode*head)  /*输出以head为头指针的单链表*/

 

      3. 实现注释    (即各项功能的实现程度)

     (1)根据输入的n值建立多项式a,b的单链表;根据提示输入每项的系数和指数。

     (2)可不按指数大小顺序任意输入多项式的每项(整数项)。

     (3)按数学格式输出a,b两多项式,然后再输出相加后的和c的多项式。

      4. 详细设计   

【1】插入函数:

int ListInsert(SLNode *head,DaTatype xishu,DaTatype zhishu)//插入

{

       SLNode *p,*q;

       p=head;

       while(p->next!=NULL)

       {

              if((p->next->zhishu)>zhishu)break;               //比较指数大小

              p=p->next;                                       //链表中节点指数大,则比较链表下一个

       }

       q=(SLNode*)malloc(sizeof(SLNode));                   //链表中节点指数小,则在该节点前插入

       q->xishu=xishu;

       q->zhishu=zhishu;

       q->next=NULL;

       q->next=p->next;

       p->next=q;

       return 1;

}

【2】求和函数:

int ListAdd(SLNode*head1,SLNode*head2,SLNode*head3)

{

       SLNode *p,*q,*s,*r;

       int n=0;

    p=head1;q=head2;s=head3;

       while(p->next!=NULL)                                //先将a存入c中

       {

           r=(SLNode*)malloc(sizeof(SLNode));

              r->zhishu=p->next->zhishu;

              r->xishu=p->next->xishu;

              r->next=NULL;

        s->next=r;

              p=p->next;

              s=s->next;

       }

       s=head3;

       while(s->next!=NULL &&q->next!=NULL )

       {

            while(s->next!=NULL && s->next->zhishu<q->next->zhishu)//搜寻          {

         s=s->next;

         if(s->next!=NULL)n=1;

         if(n){

            if( s->next->zhishu==q->next->zhishu )

               {

                    if(s->next->xishu+q->next->xishu!=0)

                    {s->next->xishu=s->next->xishu+q->next->xishu;

                    s=s->next;}

            else s->next=s->next->next;

               }

         else

         {

               r=(SLNode*)malloc(sizeof(SLNode));

                r->zhishu=q->next->zhishu;

               r->xishu=q->next->xishu;

                  r->next=s->next;

            s->next=r;

            s=s->next;

               }//插入               

           q=q->next;

           n=0;

                 }

       }

    if(q->next!=NULL&&s->next==NULL)s->next=q->next;      //剩余项的接到C链表的尾部

       return 1;

}【3】输出函数(系数为0的项已被删除):

int ListGet(SLNode *head)                                   //输出

{

       SLNode *p;

       p=head->next;

       int kaiguan=1;

       if(p==NULL)printf("0\n");                      //判断头结点为空的输出

        while(p!=NULL)                                //判断头结点非空

       {

              if(kaiguan==1)                             //多项式第一项的输出

              {

                     if(p->zhishu==0)              //当指数为时,只输出系数xishu

                            printf("%d",p->xishu);

            else if(p->xishu==1)              //系数为1时输出X^zhishui或x

               {if(p->zhishu==1)printf("x");

                else  printf("x^%d",p->zhishu);

               }

                     else if(p->xishu==-1)         //系数为-1时输出-X^zhishui或-x

                        {if(p->zhishu==1)printf("-x");

                else  printf("-x^%d",p->zhishu);

               }

                     else if(p->xishu>0)          //系数大于0时

               {if(p->zhishu==1)printf("%dx",p->xishu);

                else printf("%dx^%d",p->xishu,p->zhishu);

               }          

                     else if(p->xishu<0)               //系数为负数时,原样输出

               {if(p->zhishu==1)printf("%dx",p->xishu);

                else printf("%dx^%d",p->xishu,p->zhishu);

               }

                     kaiguan=0;

              }

              else{           //多项式的其余项都前带符号输出

                     if(p->zhishu==0)

                     {if(p->xishu!=0)

                     printf("+%d",p->xishu);

                     }

                  else if(p->xishu==1)                          

               {if(p->zhishu==1)printf("+x");

                else  printf("+x^%d",p->zhishu);

               }

                     else if(p->xishu==-1)                         

                        {if(p->zhishu==1)printf("-x");

                else  printf("-x^%d",p->zhishu);

               }

                     else if(p->xishu>0)    //系数大于0时,系数前面带“+”

               {if(p->zhishu==1)printf("+%dx",p->xishu);

                else printf("+%dx^%d",p->xishu,p->zhishu);

               }                 

                     else if(p->xishu<0)       //系数为负时,原样输出

               {if(p->zhishu==1)printf("%dx",p->xishu);

                else printf("%dx^%d",p->xishu,p->zhishu);

               }                 

              }

              p=p->next;

       }

       printf("\n");

       return 1;

}   

 

三、调试分析

   1.调试过程中遇到的主要问题是如何解决的;

调试过程中存在少许C语言的基础语法错误,经独立仔细观察和调试修改正确,最大的难题是将各多项式按数学格式输出,经过很多次的调试,还是存在错误,向同学请教,仍不能解决,最后重新修改算法,最终达到输出要求。

部分错误:

 

 

                  

2.时间和空间复杂度的分析;

       【1】插入函数: 时间O(n^2),空间O(n)

       【2】求和函数:时间O(m+n),空间O(m+n)

       【3】输出函数(系数为0的项已被删除):时间O(n),空间O(1)

 

3.改进设想;

(1)求和函数:将多项式a的链表复制给多项式c的链表,再调用求和函数(b的链表和c的链表相加),将求和的结果插入到c的链表中(作为多项式c)。

  修改思路:将多项式a的各项先与多项b的各项比较,运算后再插入多项式c的链表,(由于a,b多项式已按指数由小到大排序)修改后时间复杂度降低。

(2)输出函数:设计按数学格式输出时,算法多样。

4.经验和体会等。

    深刻体会到多动手的重要性,只有多动手编程,才能熟练灵活的掌握C语言基础知识,才能更好的理解掌握数据结构的精髓。从而避免基础语法错误,让代码变得更简洁高效。如此才能准确高效的解决问题。

四、用户手册(即使用说明)

    仅需按照提示输入数字即可。

五、运行结果

  运行环境:C-free

1.(1+x+x2+x3+x4+x5)+(-x3-x4)=(1+x+x2+x5)

            2. (x+x100)+(x100+x200)=(x+2x100+x200)

 3.(2x+5x8-3x11)+(7-5x8+11x9)=(7+2x+11x9-3x11)

 

4.(-x+2x3)+( x-2x3)=0

 

六、源程序清单

https://wenku.baidu.com/view/a114cb269a89680203d8ce2f0066f5335b81671f

 

posted on 2013-04-07 19:59  雨钝风轻  阅读(2254)  评论(0编辑  收藏  举报