您的位置:首页 > 理论基础 > 数据结构算法

一元稀疏多项式简单计算器

2018-01-14 12:06 183 查看
题目:设计一个一元稀疏多项式简单计算器

班级:1603014 姓名:钱宇珊  学号:1603014  完成日期:

一、需求分析

1.首先需要判断是加运算还是减运算,然后输入并建立多项式,输入时各项顺序不限,程序可自动排序。

2.输出多项式, 本程序将采用类数学表达式的输出形式,例如项x7的输出形式为x^7.且系数值为1的非零次项的输出形式中略去系数1,如项1x8的输出形式为 x8, 项-1x3的输出形式为-x3,序列按指数降序排列。

3.多项式a和b相加,建立多项式a+b。

4.多项式a和b相减, 建立多项式a-b。

5. 本程序以用户和计算机的对话形式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入程序中规定的运算命令来决定相关运算。

6. 程序执行的命令包括:

1)输入0、1判断加减运算;2)输入多项式的项数;3)输入多项式的系数和指数.

7. 测试数据

(1)(2x + 5x8 - 3.1x11)+ (7 - 5x8 + 11x9);

 (2)  (6x-3 – x + 4.4 x2 - 1.2x9) - (-6x-3
+5.4x2 –x2 + 7.8x15);

 (3)  (1 +x + x2 + x3 + x4 + x5) + (-x3- x4);

 (4)  (x +x3) + (-x - x3);

 (5)  (x +x100)  +  (x100+x200);

 (6)  (x +x2 + x3) + 0。

二、概要设计

为实现上述程序功能,用带表头结点的单链表存储多项式。

1)抽象数据类型一元多项式的定义如下:

ADT Polynomial {

数据对象:D = {ai  |  ai ∈ LNode, i = 1, 2,……, m,    m>=0

  LNode中的每个结点包含两个数据域和一个指针域,数据域分别为表示系数的实数和表示指数的整数,指针域指向下一个结点}

数据关系:R1 = {<ai-1 , ai> | ai-1 , ai∈ D, 且ai-1中的指数值> ai 中的指数值,i=2,…, n}

基本操作:

       CreatPolyn(Polynomial &P,int m)

  操作结果:输入m项的系数和指数,建立一元多项式P。

       AddPolyn(Polynomial &Pa,Polynomial&Pb)

  初始条件:一元多项式Pa和Pb已存在

  操作结果:完成多项式相加运算,即:Pa= Pa + Pb,并销毁一元多项式Pb。

       MinusPolyn(Polynomial &Pa,Polynomial&Pb)

  初始条件:一元多项式Pa和Pb已存在

  操作结果:完成多项式相加运算,即:Pa= Pa - Pb,并销毁一元多项式Pb。

}ADT Polynomial

2)本程序包含四个模块:

1.主程序模块­——输入数据的实现,格式的控制输出;

2.创建多项式模块——实现多项式的创建;

3.加运算模块——实现两个多项式的加运算;

4.减运算模块——实现两个多项式的减运算。

各模块之间的调用关系如下:

                         主程序模块

     

                        创建多项式模块

 

                  加运算模块       减运算模块

 

三、详细设计

1.结点类型和指针类型

typedef struct LNode{

    int expn;     //指数

    floatcoef;   //系数

    struct LNode*next;

}LNode, *Polynomial;    

 

2.根据单链表的基本操作特点,使用带头结点的单链表存储多项式

void CreatPolyn(Polynomial &P,int m)

{

    //输入m项的系数和指数,建立表示一个多项式的有序链表P

    LNode*q,*pre,*s;

    int i;

    P=new LNode;

    P->next=NULL;                          //先建立一个带头结点的单链表

    for(i=1;i<=m;i++)                      //依次输入m个非零项

    {

       s=new LNode;                       //生成新结点

        cin>>s->coef>>s->expn;                 //输入元素值

       if(s->coef!= 0){

       pre=P;                             //pre用于保存q的前驱,初值为头结点

       q=P->next;

       while(q&& q->expn > s->expn)          //通过比较指数找到第一个小于或等于输入项指数的项q

       {

           pre=q;

           q=q->next;

       }

       if(q&& q->expn == s->expn){

                                              //如果输入元素和链表中已有的元素指数相等,则合并,否则,插入到它的前面

         q->coef= q->coef + s->coef;

          deletes;

       }

       else{

       s->next=q;

       pre->next=s;

       }

       }

    }

}                               //CreatPolyn

 

void AddPolyn(Polynomial &Pa,Polynomial &Pb) {

    //多项式加法:Pa=Pa+Pb,利用两个多项式的结点构成“和多项式”

    LNode*r,*p1,*p2,*p3;

    float sum;

    p1=Pa->next;p2=Pb->next;               //p1和p2初值分别指向Pa和Pb的第一个结点

    p3=Pa;                                 //p3指向和多项式的当前结点,初值为Pa

    while(p1&& p2)                           //p1和p2均非空

    {

       if(p1->expn== p2->expn)           //指数相等

       {

           sum=p1->coef+p2->coef;              //sum保存两项的系数和

           if(sum!=0)                      //系数和不为0

           {

              p1->coef=sum;               //修改Pa当前结点p1的系数值为两项系数的和

              p3->next=p1;p3=p1;              //将修改后的Pa当前结点p1链在p3之后,p3指向p1

              r=p2;p2=p2->next;deleter;      //删除Pb当前结点r

              p1=p1->next;                //p1指向后一项

 

           }

           else                            //系数和为0

           {

              r=p1;p1=p1->next;deleter;      //删除Pb当前结点p1

              r=p2;p2=p2->next;deleter;      //删除Pb当前结点p2

           }

       }

       elseif(p1->expn > p2->expn)              //Pa指数大

       {

           p3->next=p1;                    //将p1链在p3之后

           p3=p1;                          //p3指向p1

           p1=p1->next;                    //p1指向后一项

       }

       else                               //Pb指数大

       {

           p3->next=p2;                    //将p2链在p3之后

           p3=p2;                          //p3指向p2

           p2=p2->next;                    //p2指向后一项

       }

    }

    p3->next=p1?p1:p2;                        //插入非空多项式的剩余段

    delete Pb;                             //释放Pb的头结点

}                                         //AddPolyn

 

void MinusPolyn(Polynomial &Pa,Polynomial &Pb) {

    //多项式加法:Pa=Pa+Pb,利用两个多项式的结点构成“和多项式”

    LNode*r,*p1,*p2,*p3;

    float sum;

    p1=Pa->next;p2=Pb->next;               //p1和p2初值分别指向Pa和Pb的第一个结点

    p3=Pa;                                 //p3指向和多项式的当前结点,初值为Pa

    while(p1&& p2)                           //p1和p2均非空

    {

       if(p1->expn== p2->expn)           //指数相等

       {

           sum=p1->coef - p2->coef;           //sum保存两项的系数差

           if(sum!= 0)                       //系数和不为0

           {

              p1->coef=sum;               //修改Pa当前结点p1的系数值为两项系数的差

              p3->next=p1;p3=p1;              //将修改后的Pa当前结点p1链在p3之后,p3指向p1

              r=p2;p2=p2->next;deleter;     //删除Pb当前结点r

              p1=p1->next;                //p1指向后一项

 

           }

           else                            //系数和为0

           {

              r=p1;p1=p1->next;deleter;      //删除Pb当前结点p1

              r=p2;p2=p2->next;deleter;      //删除Pb当前结点p2

           }

       }

       elseif(p1->expn > p2->expn)              //Pa指数大

       {

           p3->next=p1;                    //将p1链在p3之后

           p3=p1;                          //p3指向p1

           p1=p1->next;                    //p1指向后一项

       }

       else                               //Pb指数大

       {

           p2->coef=-p2->coef;

           p3->next=p2;                    //将p2链在p3之后

           p3=p2;                          //p3指向p2

           p2=p2->next;                    //p2指向后一项

       }

    }

    p3->next=p1?p1:p2;                        //插入非空多项式的剩余段

    delete Pb;                             //释放Pb的头结点

}

 

int main()

{//将输入项s插入到q和其前驱结点pre之间

    PolynomialPa,Pb;

    LNode *p;

    inttemp,i,flag;

    //判断是相加还是相减

   cout<<"加运算请输1,减运算请输0:  ";

   cin>>flag;

    //创建多项式Pa

    cout<<"请输入多项式Pa的项数:";

    cin>>temp;                      //输入多项式Pa的个数

    cout<<"请输入多项式Pa的系数和指数,中间用一个空格隔开,一个项一行:\n";

    CreatPolyn(Pa,temp);                   //调用函数,输入Pa每一项的系数和指数

 

    //创建多项式Pb

    cout<<"请输入多项式Pb的项数:";

    cin>>temp;                      //输入多项式Pa的个数

    cout<<"请输入多项式Pb的系数和指数,中间用一个空格隔开,一个项一行:\n";

    CreatPolyn(Pb,temp);                   //调用函数,输入Pa每一项的系数和指数

    if(flag)

    AddPolyn(Pa,Pb);

    else

   MinusPolyn(Pa,Pb);

    cout<<"多项式Pa和Pb相加后的结果是:\n";

    p=Pa->next;

    if(p == NULL)

       cout<<0;

    i=0;

    while(p)                               //输出相加后的结果,每一项以x^n表示

    {

       if(i&& p->coef > 0)

           cout<<"+";

       if((p->coef == 1)&&p->expn != 0)

            cout<< "x^" << p->expn;

        elseif((p->coef == -1)&&p->expn != 0)

            cout<< "-x^" << p->expn;

        elseif(p->expn == 0)

           cout<<p->coef;

        else

       cout<<p->coef<<"x^"<<p->expn;

       p=p->next;

       i++;

    }

 

    cout<<endl;

    return 0;

}

 

 

四、调试分析

1.刚开始没有考虑到一个多项式中会出现多个相同指数的情况,导致测试数据(2)无法得到正确情况。

2.创建多项式时,加入处理同指数的代码,可是忘记考虑链表初始为空的情况,导致一直出现未知指针运行错误。

3.本程序的模块划分较为合理,模型抽象化合理,建立一个可以包含指数系数的单链表结点。

4.本程序操作简便,思想严密,创建多项式就采用降序比较插入的方法。

5.算法的时空分析

1)本程序采用带头结点的有序单链表,各种操作的算法时间复杂度比较合理。

2)基于单链表的各种运算和操作的时间复杂度如下:

创建多项式算法CreatPolyn读入n个元素,每读入一个元素要和当前已存在链表中的元素比较,确定其插入位置后,才进行后续操作,所以时间复杂度为(n2)。

求多项式的加运算,遍历了两个多项式,将两个多项式的m和n个元素添加到pa多项式中,所以时间复杂度为(m + n ).

求多项式的减运算,同上,时间复杂度为(m+ n)。

五、用户手册

1.本程序的运行环境为windows操作系统,执行文件为:稀疏多项式.cpp。

2.进入演示程序后即显示文本方式的用户界面:

3. 输入相应命令后,进入createPolyn,按提示输入数据,结束符为“回车符”:

 

 

 

 

 

 

 

 

 

 

 

 

4.执行运算,显示相应结果:

 

六、 测试结果

1)输入 (2x + 5x8 -3.1x11) + (7 - 5x8 + 11x9),输出为-3.1x11 + 11x9+2x +7;

2)输入 (6x -3 – x + 4.4 x2 - 1.2x9) -(-6x-3
+ 5.4x2 –x2 + 7.8x15),输出为-7.8x15 - 1.2x9– x +12x-3+;

3)输入 (1 + x + x2 + x3 + x4 + x5)+ (-x3 - x4) ,输出为x5 + x2
+ x + 1;

4)输入 (x + x3) + (-x - x3) ,输出为0;

5)输入 (x + x100)  +  (x100+x200) ,输出为x200 + 2x100+ x;

6)输入 (x + x2 + x3) + 0,输出为x3 + x2 +x.

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构