02-线性结构2 一元多项式的乘法与加法运算

349 阅读6分钟

题目描述

设计函数分别求两个一元多项式的乘积与和。

输入格式

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

输入样例

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

输出样例

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

题解

1. 多项式的表示

数据结构设计:

typedef struct PolyNode *Polynomial;

struct PolyNode {
    int coef;
    int expon;
    Polynomial Next;
};

2. 程序框架搭建

主函数:

  • 读入多项式
  • 两个多项式相乘
  • 两个多项式相加
  • 多项式输出
int main()
{

    Polynomial P1, P2, ProductP, SumP;
    P1 = ReadPoly();
    P2 = ReadPoly();
    ProductP = Mult(P1, P2);
    SumP = Add(P1, P2);
    PrintPoly(ProductP);
    PrintPoly(SumP);
    return 0;

}

读入多项式:

  • 先读每行第一个数,表示非零项的个数
  • 循环读入每组数,一个是系数,一个是指数
  • 用 Attach 函数将读到的内容转化为链表结点添加到多项式链表上

Attach 函数接口:系数、指数、多项式最后一个结点的指针的引用(传引用进去,因为需要改变 rear 的值)。操作对象是带头结点的链表。操作结果是生成一个结点连接到链表末尾。

void Attach(int c, int e, Polynomial *rear)
{

    Polynomial p = (Polynomial)malloc(sizeof(struct PolyNode));
    p->coef = c;
    p->expon = e;
    p->Next = NULL;
    (*rear)->Next = p;
    (*rear) = p;

}

读入函数:因为使用 Attach 函数更方便,所以先构造带头结点的链表。但最后做加法乘法时不需要头结点。返回的时候再把头结点删掉。

Polynomial ReadPoly()
{
    int n, c, e;
    Polynomial front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    Polynomial rear = front;
    
    scanf("%d", &n);
    while (n--) {
        scanf("%d %d", &c, &e);
        Attach(c, e, &rear);
    }
    
    Polynomial t = front;
    front = front->Next;
    free(t);
    return front;
}

3. 加法、乘法运算及多项式输出

  1. 加法

传入两个先前读好的不带头结点的多项式链表,进行加法操作。操作结果为构造一个新的带头结点的链表。

  • 两个链表的第一项指数比较
    • 如果指数相同,就相加后用 Attach 函数追加结点。注意当两项抵消时不用添加结点。操作完毕后两个指针同时后移一位。
    • 如果指数不同,就将大的结点追加到结果链表上。操作完毕后指针后移一位。
  • 当有一个链表操作结束后跳出循环,将剩下那个链表后的结点全部追加到结果链表上。返回结果链表。
Polynomial Add(Polynomial P1, Polynomial P2)
{

    Polynomial p1 = P1;
    Polynomial p2 = P2;
    Polynomial front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    Polynomial rear = front;

    while (p1 && p2) {
        if (p1->expon == p2->expon) {
            if (p1->coef + p2->coef != 0) {
                Attach(p1->coef + p2->coef, p1->expon, &rear);
            }
            p1 = p1->Next;
            p2 = p2->Next;
        } else if (p1->expon > p2->expon) {
            Attach(p1->coef, p1->expon, &rear);
            p1 = p1->Next;
        } else if (p1->expon < p2->expon) {
            Attach(p2->coef, p2->expon, &rear);
            p2 = p2->Next;
        }
    }

    while (p1) {
        Attach(p1->coef, p1->expon, &rear);
        p1 = p1->Next;
    }
    while (p2) {
        Attach(p2->coef, p2->expon, &rear);
        p2 = p2->Next;
    }

    return front;
}
  1. 乘法

模拟多项式相乘排列组合的过程

  • 首先特判,一旦有一个多项式为 0 结果就为零,这里直接返回带头结点的空链表
  • 构造多项式乘积
    • 用 p1 的第一项去乘 p2 的每一项,这样乘出来一个多项式,用 Attach 可以先很方便地得到
    • 然后 p1 后移一位,开始逐项相乘插入前面的多项式
      • p2 指针归位,开始一项一项乘
      • 外层循环遍历 p1
      • 内层循环遍历 p2
    • 内部插入:
      • 先求出系数和次数
      • 再遍历结果多项式寻找插入点,在 rear 后一个结点的次数小于等于 e 的时候停下来
        • 如果是小于 e ,直接构造新结点前插
        • 如果等于 e ,不用构造新结点,但需要合并。合并时要看合并后系数是否等于零
          • 如果不等于零,直接系数相加合并
          • 如果等于零,还要删除原多项式的结点
Polynomial Mult(Polynomial P1, Polynomial P2)
{

    Polynomial p1, p2, front, rear, t;
    p1 = P1;
    p2 = P2;
    front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    rear = front;
    int c, e;
  
    if (!p1 || !p2) return front;

    while (p2) {
        Attach(p1->coef * p2->coef, p1->expon + p2->expon, &rear);
        p2 = p2->Next;
    }

    p1 = p1->Next;
    while (p1) {
        p2 = P2;
        rear = front;
        while (p2) {
            c = p1->coef * p2->coef;
            e = p1->expon + p2->expon;
            while (rear->Next && rear->Next->expon > e) rear = rear->Next;

            if (rear->Next && rear->Next->expon == e) {
                if (rear->Next->coef + c) {
                    rear->Next->coef += c;
                } else {
                    t = rear->Next;
                    rear->Next = t->Next;
                    free(t);
                }
            } else {
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef = c;
                t->expon = e;
                t->Next = rear->Next;
                rear->Next = t;
                rear = rear->Next;
            }
  
            p2 = p2->Next;
        }
        p1 = p1->Next;
    }
  
    return front;
}
  1. 多项式输出

计算出来的结果链表是带头结点的链表,输出的时候从链表的第二个结点开始输出。

  • 如果第二个结点为空结点,特判输出 0 0
  • 如果第二个节点不为空,第一项输出特殊处理再统一输出后面的项
void PrintPoly(Polynomial P)
{

    Polynomial p = P->Next;
    if (p) {
        printf("%d %d", p->coef, p->expon);
        p = p->Next;
    } else {
        printf("0 0");
    }

    while (p) {
        printf(" %d %d", p->coef, p->expon);
        p = p->Next;
    }

    printf("\n");
}

完整代码

#include <stdio.h>
#include <stdlib.h>
  
typedef struct PolyNode *Polynomial;
struct PolyNode {
    int coef;
    int expon;
    Polynomial Next;
};
  
void Attach(int c, int e, Polynomial *rear)
{
    Polynomial p = (Polynomial)malloc(sizeof(struct PolyNode));
    p->coef = c;
    p->expon = e;
    p->Next = NULL;
    (*rear)->Next = p;
    (*rear) = p;
}

Polynomial ReadPoly()
{
    int n, c, e;
    Polynomial front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    Polynomial rear = front;
    scanf("%d", &n);
    while (n--) {
        scanf("%d %d", &c, &e);
        Attach(c, e, &rear);
    }
  
    Polynomial t = front;
    front = front->Next;
    free(t);
    return front;
}

Polynomial Mult(Polynomial P1, Polynomial P2)
{
    Polynomial p1, p2, front, rear, t;
    p1 = P1;
    p2 = P2;
    front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    rear = front;
    int c, e;
  
    if (!p1 || !p2) return front;

    while (p2) {
        Attach(p1->coef * p2->coef, p1->expon + p2->expon, &rear);
        p2 = p2->Next;
    }
  
    p1 = p1->Next;
    while (p1) {
        p2 = P2;
        rear = front;
        while (p2) {
            c = p1->coef * p2->coef;
            e = p1->expon + p2->expon;
            while (rear->Next && rear->Next->expon > e) rear = rear->Next;

            if (rear->Next && rear->Next->expon == e) {
                if (rear->Next->coef + c) {
                    rear->Next->coef += c;
                } else {
                    t = rear->Next;
                    rear->Next = t->Next;
                    free(t);
                }
            } else {
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef = c;
                t->expon = e;
                t->Next = rear->Next;
                rear->Next = t;
                rear = rear->Next;
            }
  
            p2 = p2->Next;
        }
        p1 = p1->Next;
    }
  
    return front;
}
  
Polynomial Add(Polynomial P1, Polynomial P2)
{
    Polynomial p1 = P1;
    Polynomial p2 = P2;
    Polynomial front = (Polynomial)malloc(sizeof(struct PolyNode));
    front->Next = NULL;
    Polynomial rear = front;
  
    while (p1 && p2) {
        if (p1->expon == p2->expon) {
            if (p1->coef + p2->coef != 0) {
                Attach(p1->coef + p2->coef, p1->expon, &rear);
            }
            p1 = p1->Next;
            p2 = p2->Next;
        } else if (p1->expon > p2->expon) {
            Attach(p1->coef, p1->expon, &rear);
            p1 = p1->Next;
        } else if (p1->expon < p2->expon) {
            Attach(p2->coef, p2->expon, &rear);
            p2 = p2->Next;
        }
    }
  
    while (p1) {
        Attach(p1->coef, p1->expon, &rear);
        p1 = p1->Next;
    }
    while (p2) {
        Attach(p2->coef, p2->expon, &rear);
        p2 = p2->Next;
    }
  
    return front;
}
  
void PrintPoly(Polynomial P)
{
    Polynomial p = P->Next;
    if (p) {
        printf("%d %d", p->coef, p->expon);
        p = p->Next;
    } else {
        printf("0 0");
    }
  
    while (p) {
        printf(" %d %d", p->coef, p->expon);
        p = p->Next;
    }
  
    printf("\n");
}
  
int main()
{
    Polynomial P1, P2, ProductP, SumP;
    P1 = ReadPoly();
    P2 = ReadPoly();
    ProductP = Mult(P1, P2);
    SumP = Add(P1, P2);
    PrintPoly(ProductP);
    PrintPoly(SumP);
    return 0;
}

严谨一些还要加上 free 多项式链表的函数