顺序表与链表实现多项式的加减乘与幂微分

1.链表实现

分为三个文件进行编写,分别为自定义头文件,实现的cpp文件与main主程序文件.

整个过程中在实现乘的函数MutiplePoly和展示的Display函数上遇到较大困难.

1)MutiplePoly:由于一开始便默认数据是按低阶到高阶的,在设计乘算法时强迫自己尽量不使用双循环来计算.关键在于找到相乘后同阶的所有项并相加,,故将两个链表各循环一遍存入两个数组中方便访问.在将两个多项式各个系数相乘的结果规律排列成矩阵后,发现相乘后的阶数规律排列.

如两个数组大小分别为4,3.则下标分别为0,1,2,3与0,1,2,相乘后系数相加得到如下矩阵:

0 1 2 3
1 2 3 4
2 3 4 5

矩阵中相同数字代表的项阶数相同,则按斜线划分成6层,大循环从0层开始遍历到顶层.则计算可分为两部分,一部分层数0~2,a[i]+b[j],i+j=当前层数,当j<0时跳出小循环.另一部分3~5,当i>3时跳出小循环.通过小循环将相同阶数的系数全部相加.

顺序表与链表实现多项式的加减乘与幂微分

 

 

 

2)Display:展示多项式的实现过程主要在于细节的繁多,如首项若为正项则不加符号,若为0则不显示,非首项若为0则不显示,为正项要添加正号等等.也因为这样最后的实现体跳转较多,代码显得繁琐.

顺序表实现虽然用的是vector,但基本也符合顺序表的定义,实现过程与链表相差无几.故不多赘述.

最后附上完整链表实现代码:

头文件:

#ifndef __POLY_H__
#define __POLY_H__
#include <iostream>
#include <vector>
using namespace std;

// 存储系数的结构体,采用双链表结构
typedef struct data
{
    int coefficient;
    struct data *next;
    struct data *pre;
} Data;
typedef Data *PtrToNode;

// 存储链表首末位置的结构体
typedef struct upper
{
    PtrToNode head;
    PtrToNode end;
    int items;
} list;

//声明链表
typedef list *List;

void InitList(List &);                     //初始化链表
void Add(List &);                          //添加数据
void AddNode(List &);                      //添加节点
void GetInfo(List &);                      //输入数据
void Calculate(List &);                    //运用霍纳法则进行计算
void AddPoly(List &, List &, List &);      //将两个多项式相加
void SubtractPoly(List &, List &, List &); //将两个多项式相减
void MutiplePoly(List &, List &, List &);  //将两个多项式相乘
// void DividePoly(List &, List &, List &);
void Differential(List &);
void Clear(List &);                                             //清空列表
void Reset(List &, List &);                                     //重新输入两个多项式
void menu1();                                                   //展示菜单1
void menu2();                                                   //展示菜单2
void Display(List &);                                           //展示多项式
void ListToArray(List &, List &, vector<int> &, vector<int> &); //将链表数据转化为数组存储
void DeleteHead(List &);                                        //删除首节点
#endif

 

实现文件:

#include "poly.h"

//给多项式添加信息
void Add(List &l)
{
    int num;
    cout << "Enter the number of terms:" << endl;
    cin >> num;
    cout << "Enter the coefficients in ascending power:" << endl; //提醒用户以幂次的升序输入系数
    for (int i = 0; i < num; i++)
    {
        AddNode(l);
        GetInfo(l);
    }
}

// 初始化链表
void InitList(List &l)
{
    l = (List) new list;
    l->head = NULL;
    l->end = NULL;
    l->items = 0;
}

//多项式相加
void AddPoly(List &l1, List &l2, List &l3)
{
    PtrToNode cur1 = l1->head;
    PtrToNode cur2 = l2->head;
    while (cur1 != NULL || cur2 != NULL)
    {
        AddNode(l3);
        if (cur1 != NULL && cur2 != NULL)
        {
            l3->end->coefficient = cur1->coefficient + cur2->coefficient;
            cur1 = cur1->next;
            cur2 = cur2->next;
        }
        else if (cur1 == NULL) //处理多项式项数不同的情况
        {
            l3->end->coefficient = cur2->coefficient;
            cur2 = cur2->next;
        }
        else
        {
            l3->end->coefficient = cur1->coefficient;
            cur1 = cur1->next;
        }
    }
    Display(l3);
}

// 多项式相减
void SubtractPoly(List &l1, List &l2, List &l3)
{
    PtrToNode cur1 = l1->head;
    PtrToNode cur2 = l2->head;
    while (cur1 != NULL || cur2 != NULL)
    {
        AddNode(l3);
        if (cur1 != NULL && cur2 != NULL)
        {
            l3->end->coefficient = cur1->coefficient - cur2->coefficient;
            cur1 = cur1->next;
            cur2 = cur2->next;
        }
        else if (cur1 == NULL)
        {
            l3->end->coefficient = -cur2->coefficient;
            cur2 = cur2->next;
        }
        else
        {
            l3->end->coefficient = cur1->coefficient;
            cur1 = cur1->next;
        }
    }
    Display(l3);
}
void MutiplePoly(List &l1, List &l2, List &l3)
{
    vector<int> a1;
    vector<int> a2;
    ListToArray(l1, l2, a1, a2);

    //根据幂次相加后形成的规律矩阵查找每个幂次对应的项并相加,最后赋值
    int top = (l1->items + l2->items - 2);
    int floor = 0; //幂次为0开始
    int border = a2.size() - 1;
    int sum = 0; //存储每个幂次对应的系数
    while (floor <= top)
    {
        AddNode(l3);
        if (floor <= border)
            for (int i = 0, j = floor - i; j >= 0; i++, j--)
            {
                sum += a1[i] * a2[j];
                l3->end->coefficient = sum;
            }
        else
            for (int j = border, i = floor - j; i < a1.size() && j >= 0; i++, j--)
            {
                sum += a1[i] * a2[j];
                l3->end->coefficient = sum;
            }
        sum = 0;
        floor++;
    }
    Display(l3);
}

// 求一阶导
void Differential(List &l)
{
    DeleteHead(l);

    int time = 1;
    PtrToNode cur = l->head;
    while (cur != NULL)
    {
        cur->coefficient *= time;
        cur = cur->next;
        time++;
    }
    Display(l);
}

void Calculate(List &l)
{
    //获得x值
    int x;
    cout << "Enter the value of x:" << endl;
    cin >> x;

    PtrToNode cur = l->end; //按照霍纳法则从后往前遍历
    int poly = 0;
    while (cur != NULL)
    {
        poly = x * poly + cur->coefficient; //将多项式进行拆分成相乘形式
        cur = cur->pre;
    }
    cout << "The result is " << poly << endl;
}

//两个菜单
void menu1()
{
    cout << "Choose one to execute:" << endl;
    cout << "a)Add\nb)Subtract\nc)Mutiply" << endl;
}
void menu2()
{
    cout << "Choose one to execute:" << endl;
    cout << "a)Calculate\nb)Retype the two polynomials\nc)Differential\nq)quit" << endl;
}

//获得系数
void GetInfo(List &l)
{
    cin >> l->end->coefficient;
}

void AddNode(List &l)
{
    PtrToNode newNode = (PtrToNode) new Data;
    newNode->next = NULL;
    newNode->pre = l->end;
    if (l->head == NULL)
    {
        l->head = newNode;
        l->end = newNode;
    }
    else
    {
        l->end->next = newNode;
        l->end = newNode;
    }
    l->items++;
}

//清除结果
void Clear(List &l)
{
    PtrToNode cur = l->head;
    PtrToNode temp;
    while (cur != NULL)
    {
        temp = cur->next;
        free(cur);
        cur = temp;
    }
    l->head = NULL;
    l->end = NULL;
    l->items = 0;
}

//重设l1,l2
void Reset(List &l1, List &l2)
{
    Clear(l1);
    Clear(l2);
    Add(l1);
    Add(l2);
}

//将多项式以字符串形式展示
void Display(List &l)
{
    string polynomial;
    PtrToNode cur = l->head;
    if (l->items == 0)
        polynomial.append("0");
    else //遍历以确定系数是否全为0
    {
        int cnt = 0;
        while (cur != NULL)
        {
            if (cur->coefficient == 0)
                cnt++;
            cur = cur->next;
        }
        if (cnt == l->items)
        {
            polynomial.append("0");
            cout << polynomial << endl;
            return;
        }
    }

    //通过不断将系数与符号append到string中从而展示

    int time = 0; //记录幂的次数
    cur = l->head;
    while (cur != NULL)
    {
        if (cur == l->head)
        {
            if (cur->coefficient != 0)
                polynomial.append(to_string(cur->coefficient));
            cur = cur->next;
            time++;
            continue;
        }
        else
        {
            if (cur->coefficient > 0)
                polynomial.append("+");
            else if (cur->coefficient < 0)
                polynomial.append("-");
            else //系数为零则跳过不显示
            {
                cur = cur->next;
                time++;
                continue;
            }
            polynomial.append(to_string(abs(cur->coefficient)));
            polynomial.append("x^");
            polynomial.append(to_string(time));
            time++;
            cur = cur->next;
        }
    }
    cout << polynomial << endl;
}

// 将链表存储到数组当中方便访问
void ListToArray(List &l1, List &l2, vector<int> &a1, vector<int> &a2)
{
    PtrToNode p1 = l1->head;
    PtrToNode p2 = l2->head;

    //通过if,else语句让a1.a2分别固定存储长多项式于短多项式
    if (l1->items > l2->items)
    {
        while (p1 != NULL)
        {
            a1.push_back(p1->coefficient);
            p1 = p1->next;
        }

        while (p2 != NULL)
        {
            a2.push_back(p2->coefficient);
            p2 = p2->next;
        }
    }
    else
    {
        while (p1 != NULL)
        {
            a2.push_back(p1->coefficient);
            p1 = p1->next;
        }

        while (p2 != NULL)
        {
            a1.push_back(p2->coefficient);
            p2 = p2->next;
        }
    }
}

// 删除第一个节点
void DeleteHead(List &l)
{
    PtrToNode temp = l->head;
    if (l->items > 1) //项数大于1的情况
        l->head->next->pre = NULL;
    l->head = l->head->next;
    delete temp;
    l->items--;
}

 

 

 

 

 

 

主程序文件:

#include "poly.h"
int main(void)
{
    List l1;//第一个多项式
    List l2;//第二个多项式
    List l3;//操作之后的多项式
    char option;

    //初始化三个链表
    InitList(l1);
    InitList(l2);
    InitList(l3);

    //输入多项式
    Add(l1);
    Add(l2);
    do
    {
        menu1();
        cin >> option;
        switch (option)
        {
        case 'a':
            AddPoly(l1, l2, l3);
            break;
        case 'b':
            SubtractPoly(l1, l2, l3);
            break;
        case 'c':
            MutiplePoly(l1, l2, l3);
            break;
        case 'd':
            // DividePoly(l1, l2, l3);
            break;
        default:
            cout << "Invalid input" << endl;
            continue;
        }

        menu2();
        cin >> option;
        switch (option)
        {
        case 'a':
            Calculate(l3);
            break;
        case 'b':
            Reset(l1, l2);
            break;
        case 'c':
            Differential(l3);
            break;
        case 'q':
            break;
        default:
            cout << "Invalid input" << endl;
            break;
        }

        Clear(l3);
    } while (option != 'q');
}

 

上一篇:Python for Data Science - Starting with parametric methods in pandas and scipy


下一篇:彩民看过来,看老程序员如何用Python数据分析双色球基于线性回归算法预测下期中奖结果示例