算法 - 多项式加法与乘法 (c++)

题目描述:
  • 使用 链表 的数据结构实现多项式的加法和乘法。
算法描述:
  • 多项式结构表达:一个多项式就是一个链表,链表的每一项就是多项式的一个子项,故定义子项类 Subitem,包含类成员项系数、阶数、指向下一项的指针,定义多项式类Multinomial,只包含一个类成员,即指向多项式第一项的指针
  • 多项式的运算分析:多项式在运算的过程中,如果多项式a加多项式b,可以看做是将多项式b的每一项依次插入到多项式a中,同理乘法可以看做多项式a,b每两项相乘后将得到的子项依次插入到一个新的多项式中。
  • 多项式子项的插入:插入时根据阶数由大到小排列,插入的可能情况有四种(待插入多项式默认已经按照阶数大小排序,且合并同类项):
    • 插入到第一项之前,待插入多项式的系数阶数比现有多项式的第一项还大
    • 插在中间,待插入多项式的系数小于第n项,大于第n+1项
    • 插在最后,待插入多项式系数小于现有所有项
    • 合并同类项,若待插入多项式与第i项阶数相同,则将待插入项系数与该项系数相加即可
结果展示

result

问题分析:
  1. C++实现过程中,总会遇到许多有关类的问题,它不像java拥有自动的垃圾回收机制,所以必须在析构函数中对申请出来的内存进行释放,而且在对象之间的相互赋值和参数传递的过程中会遇到例如深浅拷贝的问题,这个时候一个合适的拷贝构造函数就显得很重要。在参数传递的过程中要尽量使用引用类型的参数,避免多项式在深拷贝的过程中重复执行构造函数和析构函数,降低效率。
  2. 以上实现多项式的运算实现因为要求必须使用链表,但是如果采用hashtable或者hashMap这类的数据结构,相对与效率可能会有更大的进步,在插入的时候可以使用键值对的结构。
代码展示:
//
// Created by sunhaojie on 19-3-22.
//

#ifndef TEST_MULTINOMIAL_H
#define TEST_MULTINOMIAL_H

#include <iostream>
#include <cmath>

class Subitem
{
public:
    int order;
    double coefficient;
    Subitem *next;

    Subitem(int order, double coefficient, Subitem *next = NULL)
            : order(order), coefficient(coefficient), next(next)
    {}
};

class Multinomial
{
public:
    Subitem *startItem = NULL;

    Multinomial() : startItem(NULL)
    {}

    Multinomial(Subitem *startItem, int mode = -1) : startItem(startItem)
    {
        if (mode != -1)
            Create(*this);
    }

    Multinomial(const Multinomial &m)
    {
        Copy(*this, m);
    }

    ~Multinomial()
    {
        Destroy(*this);
    }

    void Print()
    {
        if (startItem == NULL)
            std::cout << "Empty Multinomial" << std::endl;
        else
        {
            Subitem *currentItem = startItem;
            while (currentItem != NULL)
            {
                if (currentItem != startItem)
                {
                    if (currentItem->coefficient > 0)
                        std::cout << " + ";
                    else
                        std::cout << " - ";
                    std::cout << fabs(currentItem->coefficient) << "x^" << currentItem->order;
                } else
                    std::cout << currentItem->coefficient << "x^" << currentItem->order;
                currentItem = currentItem->next;
            }
        }
        std::cout << std::endl;
    }

    static Multinomial &Create(Multinomial &m)
    {
        m = Multinomial();

        int order = 0;
        double coefficient = 0;
        Subitem *currentItem = NULL;
        std::cin >> coefficient >> order;

        while (order != 0 || coefficient != 0)
        {
            if (coefficient != 0)
            {
                if (m.startItem == NULL)
                {
                    m.startItem = new Subitem(order, coefficient);
                    currentItem = m.startItem;
                } else
                {
                    currentItem->next = new Subitem(order, coefficient);
                    currentItem = currentItem->next;
                }
            }
            std::cin >> coefficient >> order;
        }
        return m;
    }

    static void Destroy(Multinomial &m)
    {
        Subitem *next = NULL;
        while (m.startItem != NULL)
        {
            next = (*m.startItem).next;
            delete m.startItem;
            m.startItem = next;
        }
    }

    static void Copy(Multinomial &des, const Multinomial &source)
    {
        Destroy(des);
        Subitem *source_currentItem = source.startItem;
        Subitem *des_currentItem = NULL;

        while (source_currentItem != NULL)
        {
            if (des.startItem == NULL)
            {
                des.startItem = new Subitem(source_currentItem->order, source_currentItem->coefficient);
                des_currentItem = des.startItem;
            } else
            {
                des_currentItem->next = new Subitem(source_currentItem->order, source_currentItem->coefficient);
                des_currentItem = des_currentItem->next;
            }
            source_currentItem = source_currentItem->next;
        }
    }

    static Multinomial &Insert(Multinomial &m, Subitem &s)
    {
        if (m.startItem == NULL)
            m.startItem = new Subitem(s.order, s.coefficient);
        else if (s.order > m.startItem->order)
        {
            Subitem *startItem = new Subitem(s.order, s.coefficient);
            startItem->next = m.startItem;
            m.startItem = startItem;
        } else```
        {```
            Subitem *currentIte```m = m.startItem;
            while (currentItem ```!= NULL)
            {```
                if (s.order == ```currentItem->order)
                {```
                    currentItem```->coefficient += s.coefficie```nt;
                    break;```
                } else if (curr```entItem->next != NULL && s.order < curre```ntItem->order &&
                           s.order > currentItem->next->order)
                {
                    Subitem *nextItem = currentItem->next;
                    currentItem->next = new Subitem(s.order, s.coefficient);
                    currentItem->next->next = nextItem;
                    break;
                } else if (currentItem->next == NULL)
                {
                    currentItem->next = new Subitem(s.order, s.coefficient);
                    break;
                }
                currentItem = currentItem->next;
            }
        }
        return m;
    }

    static Multinomial Add(Multinomial &m1, Multinomial &m2)
    {
        Multinomial result = m1;
        Subitem *currentItem = m2.startItem;

        while (currentItem != NULL)
        {
            Insert(result, *currentItem);
            currentItem = currentItem->next;
        }
        return result;
    }

    static Multinomial &MulWithSubItem(Multinomial &m, Subitem &s)
    {
        Subitem *currentItem = m.startItem;
        while (currentItem != NULL)
        {
            currentItem->coefficient *= s.coefficient;
            currentItem->order += s.order;
            currentItem = currentItem->next;
        }
        return m;
    }

    static Multinomial Mul(Multinomial &m1, Multinomial &m2)
    {
        Multinomial result = Multinomial();
        Subitem *currentItem = m2.startItem;
        while (currentItem != NULL)
        {
            Multinomial temp = m1;
            temp = MulWithSubItem(temp, *currentItem);
            Subitem *s = temp.startItem;
            while (s != NULL)
            {
                Insert(result, *s);
                s = s->next;
            }
            currentItem = currentItem->next;
        }
        return result;
    }
};

#endif //TEST_MULTINOMIAL_H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值