PTA 7-2 一元多项式的乘法与加法运算

该博客介绍了如何使用C语言实现一元多项式的加法和乘法运算。通过线性表结构存储多项式,实现了创建、插入、打印和销毁线性表的函数。多项式相加通过遍历两个线性表并合并相同指数项实现,相乘则通过每个项两两相乘再合并结果。博客提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PTA 7-2 一元多项式的乘法与加法运算

1. 题目

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

输入格式:

输入分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

2. 分析

  • 这里选用普通的线性表存储多项式。

  • 这里我们先定义一个线性表

    typedef struct Item{
        int f,l;
    }Item;
    typedef int Pos;
    typedef struct LNode{
        enum{Max=1001};
        Item Data[Max];
        Pos Last;
    }LNode;
    typedef struct LNode* List;
    

    由于题干已经给出指数不会超过1000,所以我们可以直接定义一个1001大小的数组。Item储存的是每项的系数和指数。

  • 对应的操作有:

    • 创建一个线性表

      List Create(){
          List L=(List)malloc(sizeof(LNode));
          L->Last=-1;
          return L;
       }
      
    • 在线性表的指定位置插入元素

      void Insert(List L,Item I,Pos P){
          if(L->Last==Max-1){
              printf("FULL\n");
              return;
          }
          if(P<0||P>L->Last+1){
              printf("WRONG POS\n");
              return;
          }
          for(int i=L->Last;i>=P;i--){
              L->Data[i+1]=L->Data[i];
          }
          L->Data[P]=I;
          L->Last++;
      }
      
    • 打印线性表

      void Print(List L){
          int mark=1;
          for(int i=0;i<=L->Last;i++){
              printf("%d %d",L->Data[i].f,L->Data[i].l);
              if(i!=L->Last) printf(" ");
              mark=0;
          }
          if(mark) printf("0 0");
      }
      
      • 这里需要注意的是输出的格式,以及零多项式(各项系数均为0)的处理
    • 销毁线性表

      void Destory(List L){
          free(L);
      }
      
  • 多项式相加操作

    List CalAdd(List L1,List L2){
        List L=Create();
        int i1=0;
        int i2=0;
        Item item;
        while(i1<=L1->Last&&i2<=L2->Last){
            if(L1->Data[i1].l==L2->Data[i2].l){
                item.f=L1->Data[i1].f+L2->Data[i2].f;
                item.l=L1->Data[i1].l;
                if(item.f){
                    Insert(L,item,L->Last+1);
                }
                ++i1;
                ++i2;
            }
            else{
                int l1=L1->Data[i1].l;
                int l2=L2->Data[i2].l;
                item.l=l1>l2?l1:l2;
                item.f=l1>l2?L1->Data[i1].f:L2->Data[i2].f;
                Insert(L,item,L->Last+1);
                if(l1>l2) ++i1;
                else ++i2;
            }
        }
        int begin= i1>L1->Last?i2:i1;//注意取值的条件判断越界
        int end= i1>L1->Last?L2->Last:L1->Last;
        List LL= i1>L1->Last?L2:L1;
        for(int i=begin;i<=end;i++){
            Insert(L,LL->Data[i],L->Last+1);
        }
        return L;
    }
    
    • 多项式的相加操作,其实就是合并两个线性表。如果有相同指数的项,则将系数相加,如果系数相加之后为0,则将这一项省略。
    • 最简单的做法就是遍历这两个线性表,时间复杂度为O(n^2),这显然不是我们想要的结果。
    • 那能不能通过一次遍历就将这个线性表合并呢?当然可以。首先定义两个指针(其实是数组的指数index,类型为int),分别指向两个线性表的表头。如果两个指针指向的数据指数相同,就将它们系数进行相加,送入新的线性表中(Insert操作),同时将两个指针向后移一位。如果指向的数据不同,取指数较大的数据送入新的线性表,同时它的指针向后移一位,另一个指针不动。重复这个操作,直到一个线性表遍历结束。然后将有剩余的那个线性表的剩余数据送入新线性表中(当然也可能两个都无剩余)。
  • 多项式相乘操作

    List CalMulti(List L1,List L2){
      List temp=Create();
      Item item;
      List L=Create();
      for(int i=0;i<=L1->Last;i++){
          for(int j=0;j<=L2->Last;j++){
              item.f=L1->Data[i].f*L2->Data[j].f;
              item.l=L1->Data[i].l+L2->Data[j].l;
              Insert(temp,item,temp->Last+1);
          }
          List p=L;
          L=CalAdd(L,temp);
          Destory(p);
          temp->Last=-1; /
      }
      Destory(temp);
      return L;
    }
    
    • 多项式的相乘操作即对一个多项式的每一项乘以另一个多项式的每一项,然后将结果相加。时间复杂度O(n^2),没有想到更好的解法,有更好解决办法的小伙伴可以留言,一起学习交流。

3. 全部代码

#include<stdio.h>
typedef struct Item{
   int f,l;
}Item;
typedef int Pos;
typedef struct LNode{
   enum{Max=1001};
   Item Data[Max];
   Pos Last;
}LNode;
typedef struct LNode* List;
List Create(){
   List L=(List)malloc(sizeof(LNode));
   L->Last=-1;
   return L;
}
void Destory(List L){
   free(L);
}
void Insert(List L,Item I,Pos P){
   if(L->Last==Max-1){
       printf("FULL\n");
       return;
   }
   if(P<0||P>L->Last+1){
       printf("WRONG POS\n");
       return;
   }
   for(int i=L->Last;i>=P;i--){
       L->Data[i+1]=L->Data[i];
   }
   L->Data[P]=I;
   L->Last++;
}
void Print(List L){
   int mark=1;
   for(int i=0;i<=L->Last;i++){
       printf("%d %d",L->Data[i].f,L->Data[i].l);
       if(i!=L->Last) printf(" ");
       mark=0;
   }
   if(mark) printf("0 0");
}
List CalAdd(List L1,List L2){
   List L=Create();
   int i1=0;
   int i2=0;
   Item item;
   while(i1<=L1->Last&&i2<=L2->Last){
       if(L1->Data[i1].l==L2->Data[i2].l){
           item.f=L1->Data[i1].f+L2->Data[i2].f;
           item.l=L1->Data[i1].l;
           if(item.f){
               Insert(L,item,L->Last+1);
           }
           ++i1;
           ++i2;
       }
       else{
           int l1=L1->Data[i1].l;
           int l2=L2->Data[i2].l;
           item.l=l1>l2?l1:l2;
           item.f=l1>l2?L1->Data[i1].f:L2->Data[i2].f;
           Insert(L,item,L->Last+1);
           //if(l1>l2) ++i1;
          // else ++i2;
           l1>l2? ++i1:++i2;
       }
   }
   int begin= i1>L1->Last?i2:i1;//注意取值的条件判断越界
   int end= i1>L1->Last?L2->Last:L1->Last;
   List LL= i1>L1->Last?L2:L1;
   for(int i=begin;i<=end;i++){
       Insert(L,LL->Data[i],L->Last+1);
   }
   return L;
}
List CalMulti(List L1,List L2){
   List temp=Create();
   Item item;
   List L=Create();
   for(int i=0;i<=L1->Last;i++){
       for(int j=0;j<=L2->Last;j++){
           item.f=L1->Data[i].f*L2->Data[j].f;
           item.l=L1->Data[i].l+L2->Data[j].l;
           Insert(temp,item,temp->Last+1);
       }
       List p=L;
       L=CalAdd(L,temp);
       Destory(p);
       temp->Last=-1;
   }
   Destory(temp);
   return L;
}
int main(){
   int cnt;
   Item t;
   List L1=Create();
   List L2=Create();
   scanf("%d",&cnt);
   for(int i=0;i<cnt;i++){
       scanf("%d%d",&t.f,&t.l);
       Insert(L1,t,L1->Last+1);
   }
   scanf("%d",&cnt);
   for(int i=0;i<cnt;i++){
       scanf("%d%d",&t.f,&t.l);
       Insert(L2,t,L2->Last+1);
   }
   List L3=CalAdd(L1,L2);
   List L4=CalMulti(L1,L2);
   Print(L4);
   printf("\n");
   Print(L3);
   Destory(L1);
   Destory(L2);
   Destory(L3);
   Destory(L4);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

角plusplus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值