zoukankan      html  css  js  c++  java
  • 【Weiss】【第03章】练习3.6:有序多项式相加

    【练习3.6】

    编写将两个多项式相加的函数。不要毁坏输入数据。用一个链表实现。

    如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少?

    两个按幂次升序的多项式链表,分别维护一个指针。

    幂较小者将元素的副本拷贝入节点并加入新链表,指针向后移动。

    幂同样大时,将两者的系数相加后的结果加入新链表,两个多项式链表的指针共同向前移动。

    其中一个多项式到达尾部时,如另一个未到达尾部,则一边后移一边将相同元素的新节点加入新链表。

    时间复杂度O(M+N)。

    测试代码如下:

     1 #include <iostream>
     2 #include "linklist.h"
     3 using linklist::List;
     4 using namespace std;
     5 int main(void)
     6 {
     7     //测试多项式加法
     8     List<Poly> a;
     9     a.additem(Poly(3, 1));
    10     a.additem(Poly(1, 2));
    11     a.additem(Poly(4, 3));
    12     a.additem(Poly(7, 4));
    13     a.additem(Poly(2, 5));
    14     cout << "  ( " << flush;
    15     a.traverse();
    16     cout << ")  +
    " << flush;
    17     List<Poly> b;
    18     b.additem(Poly(5, 2));
    19     b.additem(Poly(2, 3));
    20     b.additem(Poly(1, 5));
    21     b.additem(Poly(3, 7));
    22     b.additem(Poly(1, 11));
    23     cout << "  ( " << flush;
    24     b.traverse();
    25     cout << ") =
    " << flush;
    26 
    27     List<Poly> answer = linklist::polyplus(a, b);
    28     cout << "
      ( " << flush;
    29     answer.traverse();
    30     cout << ") 
    " << flush;
    31     system("pause");
    32 }
    View Code

    实现方面,首先定义了多项式类,以及必要的构造函数及运算符重载,放在poly.h头文件中

     1 #ifndef POLY
     2 #define POLY
     3 #include <iostream>
     4 using namespace std;
     5 
     6 namespace poly
     7 {
     8 //练习3.6新增,多项式元素定义
     9 class Poly
    10 {
    11     friend bool operator<(const Poly& poly1, const Poly& poly2);
    12     friend bool operator==(const Poly& poly1, const Poly& poly2);
    13     friend bool operator!=(const Poly& poly1, const Poly& poly2);
    14     friend ostream& operator<<(ostream &os, const Poly& poly);
    15     friend Poly operator+(const Poly& poly1, const Poly& poly2);
    16 public:
    17     Poly() = default;
    18     Poly(int coe, int exp) :coefficient(coe), exponent(exp){}
    19 private:
    20     //多项式系数
    21     int coefficient;
    22     //多项式指数
    23     int exponent;
    24 };
    25 //练习3.6新增,多项式元素对应操作符重载,包括<<、<、==、!=,+
    26 bool operator<(const Poly& poly1, const Poly& poly2)
    27 {
    28     return poly1.exponent < poly2.exponent;
    29 }
    30 bool operator==(const Poly& poly1, const Poly& poly2)
    31 {
    32     return poly1.exponent == poly2.exponent;
    33 }
    34 bool operator!=(const Poly& poly1, const Poly& poly2)
    35 {
    36     return !(poly1 == poly2);
    37 }
    38 ostream& operator<<(ostream &os, const Poly& poly)
    39 {
    40     cout << poly.coefficient << "x^" << poly.exponent << flush;
    41     return os;
    42 }
    43 Poly operator+(const Poly& poly1, const Poly& poly2)
    44 {
    45     if (poly1 != poly2)
    46         throw runtime_error("Undefined operation!");
    47     else
    48     {
    49         Poly answer;
    50         answer.coefficient = poly1.coefficient + poly2.coefficient;
    51         answer.exponent = poly1.exponent;
    52         return answer;
    53     }
    54 }
    55 }
    56 #endif

    在原链表例程中包含该头文件,并将Poly类与polyplus函数(该函数不是List的成员函数)设为友元

     1 #ifndef LINKLIST
     2 #define LINKLIST
     3 #include <iostream>
     4 #include "poly.h"      //包含poly头文件
     5 using namespace std;
     6 using namespace poly;
     7 
     8 namespace linklist
     9 {
    10         /…………/
    11  template <typename T> class List
    12 {
    13       /…………/
    14         //练习3.6新增,友元声明
    15     friend List<Poly> polyplus(const List<Poly> &inorder_a, const List<Poly> &inorder_b);
    16     friend struct Poly;   
    17        /…………/
    18 }
    19 
    20        /…………/
    21 }

    最后是具体实现代码:

     1 //练习3.6新增,不覆盖原传入数据,多项式相加
     2 List<Poly> polyplus(const List<Poly> &inorder_a, const List<Poly> &inorder_b)
     3 {
     4     List<Poly> answer;
     5     Node<Poly>* pwrite = answer.front;
     6     Node<Poly>* pread_a = inorder_a.front;
     7     Node<Poly>* pread_b = inorder_b.front;
     8     while (pread_a != nullptr && pread_b != nullptr)
     9     {
    10         //为实现升序排列,元素较小者加入新的链表,并向前移动指针
    11         if (pread_a->data < pread_b->data)
    12         {
    13             answer.additem(pread_a->data, pwrite);
    14             if (pwrite == nullptr)
    15                 pwrite = answer.front;
    16             else
    17             pwrite = pwrite->next;
    18             pread_a = pread_a->next;
    19         }
    20         else if (pread_b->data < pread_a->data)
    21         {
    22             answer.additem(pread_b->data, pwrite);
    23             if (pwrite == nullptr)
    24                 pwrite = answer.front;
    25             else
    26                 pwrite = pwrite->next;
    27             pread_b = pread_b->next;
    28         }
    29         //元素一样大时共同向前移动指针
    30         else
    31         {
    32             answer.additem(pread_a->data + pread_b->data, pwrite);
    33             if (pwrite == nullptr)
    34                 pwrite = answer.front;
    35             else
    36                 pwrite = pwrite->next;
    37             pread_a = pread_a->next;
    38             pread_b = pread_b->next;
    39         }
    40     }
    41     //如果其中任一链表未遍历,将剩余的元素复制入新的链表
    42     while (pread_a != nullptr)
    43     {
    44         answer.additem(pread_a->data, pwrite);
    45         if (pwrite == nullptr)
    46             pwrite = answer.front;
    47         else
    48             pwrite = pwrite->next;
    49         pread_a = pread_a->next;
    50     }
    51     while (pread_b != nullptr)
    52     {
    53         answer.additem(pread_b->data, pwrite);
    54         if (pwrite == nullptr)
    55             pwrite = answer.front;
    56         else
    57             pwrite = pwrite->next;
    58         pread_b = pread_b->next;
    59     }
    60     return answer;
    61 }
  • 相关阅读:
    spring MVC中定义异常页面
    Spring中bean的范围
    Linux Socket学习域和套接口简介
    MySQL学习字符串属性
    Mybatis注解学习xxxMapper is not known to the MapperRegistry
    eclipse怎样生成javadoc
    java 序列化
    使用Spring的JavaConfig
    SQLBuilder
    Linux 操作
  • 原文地址:https://www.cnblogs.com/catnip/p/4329818.html
Copyright © 2011-2022 走看看