一元多项式的乘法运算(C语言)实现

[PAT] 一元多项式的乘法与加法运算 C语言实现

[PAT] 02-线性结构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

  • 时间限制:200ms
  • 内存限制:64MB
  • 代码长度限制:16kB
  • 判题程序:系统默认
  • 作者:DS课程组
  • 单位:浙江大学

  原题点击此处

  好的,宝宝又来写东西啦~这次的题目是一道多项式计算题:输入两个多项式,输出他们的乘积与和,格式大概是这样:

  [15 24] [-25 22] [30 21] [-10 20]...

   每个中括号前面的是系数,后面的是指数,排序是指数从高到低.

 

  这题难度本身不大,做出来很容易.但是要追求速度和更少内存消耗的话还是需要考虑用什么方式去储存和处理这些数据,下面给出我个人的一个方法:求乘积用双向链表,求和用动态数组.另外,我的代码比较长,因为我采用的是"空间换时间"的总体方向,所以消耗较多储存空间,好处是不用递归函数,那个是计算机最不擅长的事情.

复制代码
#include <stdio.h>
#include <stdlib.h>
 
typedef struct 
{
    int cofe;
    int expo;
} NODE;
 
typedef struct _List
{
      int cofe;
    int expo;  
    struct _List * _next;
    struct _List * _back;        
} List;
复制代码

  构造一个NODE型的struct.存放原始每一项的系数(cofe)和指数(expo),再构造一个List型的struct,这是一个可以增长的链表,在原始数据里面不断抽取数据按指数大小进行比较排序,若指数比当前指的小就向后(左)移动一位,比当前大就向后(右)移动一位如果已经指到头则新建一个节点再写入,这其中的判断逻辑还包括系数相乘后写入系数区,排序结束后的双向链表就可以直接输出了.


复制代码
 1 int main(void) //全局初始化,包括建立各种变量以及读入原始数据
 2 {
 3     int PolyOneCount,PolyTwoCount,i,k,cofe_temp,expo_temp,flag=1,Once=1,NotZeroCount=0;
 4     NODE* PolyOne=NULL;
 5     NODE* PolyTwo=NULL;
 6     List* PL=NULL;
 7     NODE* PolySum=NULL;
 8     List* PTemp;
 9     NODE* P1=NULL;
10     NODE* P2=NULL;
11     scanf("%d",&PolyOneCount);
12     P1=PolyOne=(NODE*)malloc(PolyOneCount*sizeof(NODE));
13     for ( i=0; i<PolyOneCount; i++ ) 
14     {
15         scanf("%d",&((PolyOne+i)->cofe));
16         scanf("%d",&((PolyOne+i)->expo));
17     }
18     scanf("%d",&PolyTwoCount);
19     P2=PolyTwo=(NODE*)malloc(PolyTwoCount*sizeof(NODE));
20     for ( i=0; i<PolyTwoCount; i++ )
21     {
22         scanf("%d",&((PolyTwo+i)->cofe));
23         scanf("%d",&((PolyTwo+i)->expo));
24     }
25     List* PC=(List*)calloc(1,sizeof(List)); //PC是游走的指针,相当于一个爪子,把元素送到它需要去的地方
复制代码

  全局初始化,包括建立各种变量以及读入原始数据.  


复制代码
  1 for (i=0; i<PolyOneCount; i++) 
  2     for (k=0; k<PolyTwoCount; k++)
  3         {
  4         cofe_temp=((PolyOne+i)->cofe)*((PolyTwo+k)->cofe);
  5         expo_temp=((PolyOne+i)->expo)+((PolyTwo+k)->expo);
  6             while (1)
  7             {
  8                 if (Once)
  9                 {
 10                     PC->cofe = cofe_temp;
 11                     PC->expo = expo_temp;
 12                     PL=PC;
 13                     Once=0;
 14                     break;
 15                 } 
 16                      
 17                  
 18                 if (expo_temp > PC->expo) //元素需要后移 
 19                 {
 20                     if (PC->_next) //链表存在下一节点 
 21                     {
 22                         flag=1;
 23                         if (expo_temp > (PC->_next)->expo) //尚未到位 
 24                             PC=PC->_next;
 25                         else if (expo_temp < (PC->_next)->expo) //已到位 
 26                         {
 27                             PTemp = (List*)calloc(1,sizeof(List));
 28                             PTemp->_next = (PC->_next); 
 29                             (PC->_next)->_back = PTemp;
 30                             PC->_next = PTemp;
 31                             PTemp->_back = PC;
 32                             PC=PC->_next;
 33                             PC->cofe = cofe_temp;
 34                             PC->expo = expo_temp;
 35                             break;
 36                         }
 37                         else if (expo_temp == (PC->_next)->expo) //元素与下一个相等 
 38                         {
 39                             PC=PC->_next;
 40                             (PC->cofe)+=cofe_temp;
 41                             flag=0;
 42                             break;
 43                         }
 44                     }
 45                      
 46                     else //双向链表无下一节点. 
 47                     {
 48                         PTemp = (List*)calloc(1,sizeof(List));
 49                         PTemp->_back = PC;
 50                         PL=PTemp;
 51                         PC->_next = PTemp;
 52                         PC=PC->_next;
 53                         PC->cofe = cofe_temp;
 54                         PC->expo = expo_temp;
 55                          
 56                         break;
 57                     }                           
 58                 }
 59                  
 60                 else if (expo_temp < PC->expo) //元素需要前移 
 61                 {
 62                     if (PC->_back) //存在前驱节点 
 63                     {
 64                         flag=1;
 65                         if (expo_temp < (PC->_back)->expo) //未到位 
 66                             PC=PC->_back;
 67                         else if (expo_temp > (PC->_back)->expo) //已到位 
 68                         {
 69                             PTemp = (List*)calloc(1,sizeof(List));
 70                             PTemp->_back = (PC->_back); 
 71                             (PC->_back)->_next = PTemp;
 72                             PC->_back = PTemp;
 73                             PTemp->_next = PC;
 74                             PC=PC->_back;
 75                             PC->cofe = cofe_temp;
 76                             PC->expo = expo_temp;
 77                             break;
 78                         }
 79                         else if (expo_temp == (PC->_back)->expo)
 80                         {
 81                             PC=PC->_back;
 82                             (PC->cofe)+=cofe_temp;
 83                             flag=0;
 84                         }
 85                     } 
 86                     else //不存在前驱节点 
 87                     {
 88                         PTemp = (List*)calloc(1,sizeof(List));
 89                         PTemp->_next = PC;
 90                     //  PH=PTemp;
 91                         PC->_back = PTemp;
 92                         PC=PC->_back;
 93                         PC->cofe = cofe_temp;
 94                         PC->expo = expo_temp;
 95                         break;
 96                          
 97                     }
 98                 }       
 99              
100                 else 
101                 {
102                     if (flag) (PC->cofe)+=cofe_temp;
103                     break;
104                 }
105             }
106         }
107  PC=PL;
复制代码

  以上是乘积计算代码,Once是一个标志,用来创建第一个节点.两个for循环用来遍历所有的乘积组合,当然也是这个程序中时间复杂度最高的一段代码,达到了O(N2).


复制代码
 1    for (;PC;PC=PC->_back)  
 2     {
 3         if (PC->_back != NULL) 
 4         {
 5             if (PC->cofe) 
 6             {
 7                 printf("%d %d ",PC->cofe,PC->expo);
 8                 NotZeroCount++;
 9             } 
10             else continue;
11         }
12         else 
13         {
14             printf("%d %d\n",PC->cofe,PC->expo);
15             NotZeroCount++;
16         }
17     }
18     if (!NotZeroCount) printf("0 0\n");
19     NotZeroCount=0;
复制代码

  输出语句,中间有个if是因为题目要求最后一个不带空格;最后一个判断是看看是否是零多项式,如果是就输出"0 0"(题目要求)


复制代码
 1 int max = 0,Lowest = 0;
 2     if ( PolyOne->expo >= PolyTwo->expo ) max = PolyOne->expo;
 3     else max = PolyTwo->expo;
 4     PolySum=(NODE*)calloc(max+1,sizeof(NODE));
 5     i=k=0;
 6     for (i=0;i<PolyOneCount;i++) 
 7     {
 8         (PolySum+((PolyOne+i)->expo))->cofe += (PolyOne+i)->cofe;
 9         (PolySum+((PolyOne+i)->expo))->expo = (PolyOne+i)->expo;
10     }
11     for (i=0;i<PolyTwoCount;i++) 
12     {
13         (PolySum+((PolyTwo+i)->expo))->cofe += (PolyTwo+i)->cofe;
14         (PolySum+((PolyTwo+i)->expo))->expo = (PolyTwo+i)->expo;
15          
16     }
17        NotZeroCount=0;
18     for (i=0;i<=max;i++)
19     {
20         if( (PolySum+i)->cofe ) 
21         {
22             NotZeroCount=1;
23             Lowest=i;
24             break;
25         }
26     }
27     if (!NotZeroCount) printf("0 0");
28     else
29     for (k=max;k>=0;k--)  
30     if ((PolySum+k)->cofe != 0) 
31     {
32         
33         if (k==Lowest) printf("%d %d",(PolySum+k)->cofe,(PolySum+k)->expo);    
34         else  printf("%d %d ",(PolySum+k)->cofe,(PolySum+k)->expo);
35    
36     }
37     return 0;
38 }//这里没有写free,因为做题时追求速度就省略了这一步,但是大家应当养成"一个malloc一个free"的好习惯
复制代码

  这里是加法的处理,直接给一个NODE型数组,其大小取两个多项式中最大指数加一为数组大小.毕竟相加的指数最大值不超过单个指数的最大值,于是数组的下标就是对应指数的存放地址啦.这里不需要考虑太多,直接连续把两个多项式加到新建的数组上,加完以后用一个for检查系数是不是全是0,如果不是,再用一个for从高指数往低指数输出所有系数非0的一组数据,就此完成~

 


  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值