【数据结构】一元多项式的乘法与加法运算

15 阅读4分钟

题目连接

习题3.6 一元多项式的乘法与加法运算 - 浙大版《数据结构(第2版)》题目集

整体思路

多项式使用结构体数组顺序存储

  1. 主函数:
    1. 输入多项式
    2. 计算多项式乘法
    3. 输出多项式的乘积
    4. 输出空格
    5. 计算多项式加法
    6. 输出多项式的和
  2. 多项式乘法
    1. 遍历两个多项式的每一项,计算指数乘积、系数和
    2. 将每次计算结果按照递减顺序插入到结果多项式,注意首项和末尾项,以及系数和为0的情况
  3. 多项式加法
    1. 遍历两个多项式的每一项,将指数大的多项式插入结果多项式并自增
    2. 如果指数相等,计算系数之和,系数之和不为0插入到结果多项式
    3. 如果其中一个多项式遍历到末尾,将另一个多项式的剩余部分接到结果多项式末尾

代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct PolyItem
{
    int coef;       // 系数
    int expon;      // 指数
} Polynomial;

void PolynomialAdd(Polynomial* polynomial1, int n1, Polynomial* polynomial2, int n2, Polynomial* polynomial, int* n);
void PolynomialMul(Polynomial* polynomial1, int n1, Polynomial* polynomial2, int n2, Polynomial* polynomial, int* n);
bool InsertElement(int coef, int expon, Polynomial *polynomial, int* pToNum);
void PrintPolynomial(Polynomial *polynomial, int num);
void ReadPolynomial(Polynomial *polynomial, int num);

int main()
{
    int n1, n2;
    int num = 0;

    Polynomial* polynomial1;
    Polynomial* polynomial2;
    Polynomial* polynomialSum;
    Polynomial* polynomialProduct;

    // 输入多项式1
    scanf("%d", &n1);
    polynomial1 = (Polynomial*)malloc(sizeof(Polynomial) * n1);
    ReadPolynomial(polynomial1, n1);

    // 输入多项式2
    scanf("%d", &n2);
    polynomial2 = (Polynomial*)malloc(sizeof(Polynomial) * n2);
    ReadPolynomial(polynomial2, n2);

    polynomialSum = (Polynomial*)malloc(sizeof(Polynomial) * (n1 + n2));
    polynomialProduct = (Polynomial*)malloc(sizeof(Polynomial) * (n1 * n2));

    // 多项式乘法
    num = 0;
    PolynomialMul(polynomial1, n1, polynomial2, n2, polynomialProduct, &num);
    // 输出多项式乘积
    PrintPolynomial(polynomialProduct, num);
    
    // 输出换行符
    printf("\n");

    // 多项式加法
    num = 0;
    PolynomialAdd(polynomial1, n1, polynomial2, n2, polynomialSum, &num);
    // 输出多项式和
    PrintPolynomial(polynomialSum, num);

    // 释放申请内存
    free(polynomialSum);
    free(polynomialProduct);
    free(polynomial1);
    free(polynomial2);
    
    return 0;
}
/**
 * @brief 多项式加法
 * 
 * @param polynomial1 多项式1
 * @param n1 多项式1项数
 * @param polynomial2 多项式2
 * @param n2 多项式2项数
 * @param polynomial 多项式的和
 * @param n 多项式和项数
 */
void PolynomialAdd(Polynomial* polynomial1, int n1, Polynomial* polynomial2, int n2, Polynomial* polynomial, int* n)
{
    int i, j;
    int tempCoef;

    i = 0;
    j = 0;

    while (i < n1 && j < n2)
    {
        if (polynomial1[i].expon > polynomial2[j].expon)
        {
            polynomial[*n].coef = polynomial1[i].coef;
            polynomial[*n].expon = polynomial1[i].expon;
            i++;
            (*n)++;
        }
        else if (polynomial1[i].expon < polynomial2[j].expon)
        {
            polynomial[*n].coef = polynomial2[j].coef;
            polynomial[*n].expon = polynomial2[j].expon;
            j++;
            (*n)++;
        }
        else
        {
            // 两个项指数相等,系数相加
            tempCoef = polynomial1[i].coef + polynomial2[j].coef;
            if (tempCoef != 0)
            {
                // 系数不为0时,插入结果多项式
                polynomial[*n].coef = polynomial1[i].coef + polynomial2[j].coef;
                polynomial[*n].expon = polynomial1[i].expon;
                (*n)++;
            }
            i++;
            j++;
        }
    }

    // 将剩余项插入结果多项式
    if (i >= n1)
    {
        while (j < n2)
        {
            polynomial[*n].coef = polynomial2[j].coef;
            polynomial[*n].expon = polynomial2[j].expon;
            j++;
            (*n)++;
        }
    }
    else if (j >= n2)
    {
        while (i < n1)
        {
            polynomial[*n].coef = polynomial1[i].coef;
            polynomial[*n].expon = polynomial1[i].expon;
            i++;
            (*n)++;
        }
    }
}
/**
 * @brief 多项式乘法
 * 
 * @param polynomial1 多项式1 
 * @param n1 多项式1项数
 * @param polynomial2 多项式2
 * @param n2 多项式2项数
 * @param polynomial 多项式乘积
 * @param n 多项式乘积项数
 */
void PolynomialMul(Polynomial* polynomial1, int n1, Polynomial* polynomial2, int n2, Polynomial* polynomial, int* n)
{
    int i, j;
    int tempCoef, tempExpon;

    for (i = 0; i < n1; i++)
    {
        for (j = 0; j < n2; j++)
        {
            tempCoef = polynomial1[i].coef * polynomial2[j].coef;
            tempExpon = polynomial1[i].expon + polynomial2[j].expon;
            if (tempCoef != 0)
            {
                InsertElement(tempCoef, tempExpon, polynomial, n);
            }
        }
    }
}
/**
 * @brief 多项式1和多项式2的每一项乘积插入或合并到乘积多项式中
 * 
 * @param coef 系数
 * @param expon 指数
 * @param polynomial 乘积多项式
 * @return true 插入或合并成功
 * @return false 插入或合并失败
 */
bool InsertElement(int coef, int expon, Polynomial *polynomial, int* n)
{
    bool ret = true;
    bool done = false;
    int i = 0;
    int j = 0;

    if (*n < 0)
    {
        // 判断传入不合法的参数
        ret = false;
    }
    else if (*n == 0)
    {
        // 如果第一次插入,赋值给数组第一个元素
        polynomial[0].coef = coef;
        polynomial[0].expon = expon;
        (*n)++;
    }
    else
    {
        for (i = 0; i < *n; i++)
        {
            if (polynomial[i].expon < expon)
            {
                for (j = *n - 1; j >= i; j--)
                {
                    polynomial[j+1].coef = polynomial[j].coef;
                    polynomial[j+1].expon = polynomial[j].expon;
                }
                polynomial[i].coef = coef;
                polynomial[i].expon = expon;
                (*n)++;
                // 插入完成,标志位置为true,跳出循环
                done = true;
                break;
            }
            else if (polynomial[i].expon > expon)
            {
                continue;
            }
            else
            {
                // 系数相加为0的情况,项数减1,后续项递补
                if (polynomial[i].coef + coef == 0)
                {
                    for (j = i; j < *n - 1; j++)
                    {
                        polynomial[j] = polynomial[j+1];
                    }
                    (*n)--;
                }
                else
                {
                    // 系数相加不为0
                    polynomial[i].coef = polynomial[i].coef + coef;
                }
                // 合并完成,标志位置为true,跳出循环
                done = true;
                break;
            }
        }
        
        // 没找到插入或合并位置,插入到多项式末尾
        if (!done)
        {
            polynomial[*n].coef = coef;
            polynomial[*n].expon = expon;
            (*n)++;
        }

        ret = true;
    }

    return ret;
}
/**
 * @brief 打印多项式
 * 
 * @param polynomial 多项式 
 * @param num 项数
 * @param lineBreak 结尾是否需要打印换行
 */
void PrintPolynomial(Polynomial *polynomial, int num)
{
    int i;

    if (num == 0)
    {
        printf("0 0");

        return;
    }

    for (i = 0; i < num; i++)
    {
        printf("%d ", polynomial[i].coef);
        if (i == num - 1)
        {
            printf("%d", polynomial[i].expon);
        }
        else
        {
            printf("%d ", polynomial[i].expon);
        }
    }

    return;
}
/**
 * @brief 读入多项式
 * 
 * @param polynomial 多项式 
 * @param num 项数
 */
void ReadPolynomial(Polynomial *polynomial, int num)
{
    int i;

    for (i = 0; i < num; i++)
    {
        scanf(" %d", &polynomial[i].coef);
        scanf(" %d", &polynomial[i].expon);    
    }

    return;
}