程序设计入门——C语言 第7周编程练习
1多项式加法(5分)
题目内容:
一个多项式可以表达为x的各次幂与系数乘积的和,比如:
2x6+3x5+12x3+6x+20
现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出。
程序要处理的幂最大为100。
输入格式:
总共要输入两个多项式,每个多项式的输入格式如下:
每行输入两个数字,第一个表示幂次,第二个表示该幂次的系数,所有的系数都是整数。第一行一定是最高幂,最后一行一定是0次幂。
注意第一行和最后一行之间不一定按照幂次降低顺序排列;如果某个幂次的系数为0,就不出现在输入数据中了;0次幂的系数为0时还是会出现在输入数据中。
输出格式:
从最高幂开始依次降到0幂,如:
2x6+3x5+12x3-6x+20
注意其中的x是小写字母x,而且所有的符号之间都没有空格,如果某个幂的系数为0则不需要有那项。
输入样例:
6 2
5 3
3 12
1 6
0 20
6 2
5 3
2 12
1 6
0 20
输出样例:
4x6+6x5+12x3+12x2+12x+40
时间限制:500ms内存限制:32000kb
这道题如果是第一次见的话可能觉得很简单,随随便便写个40行的代码就上交,结果得了个0蛋。
主要可能错的地方有以下几个个:
1、输入幂次的系数为负时,中间要以-相连(鉴于负号和减号不是同一个运算符,所以我用的是减号,不知道负号能不能过检测)例如:输入了10 -2,9 -2,要输出-2x10-2x9。
2、系数为一或负一时前面的系数要省略,例如输入10 1,9 1时,输出应为x10+x9;而不是1x10+1x9。
3、幂次为一时幂次要省略,例如输入1 10时,输出应为10x,而非10x1。
4、第一项系数为正前边不需要带符号,但是为负时前边需要带减号。
由以上几个注意事项,可以把代码分成几块。
最后面有完整的代码。
第一部分,输入数据
#include<stdio.h>
#include<math.h>
int main()
{
int x,y,max=0,a[101]={0}; //初始化数组,让里面的元素全为零
for(int i=0;i<2;i++) //两个多项式相加,要做两次输入。
{
do
{
scanf("%d %d",&x,&y);
a[x] += y;
}while(x!=0); //最后一次输入的幂次为零,可以作为循环结束的条件。
}
第二部分,寻找幂次最大项
这部分的目的主要是方便第一次输出(第一次输出前面不能带正号),不过会让后面的代码加多几个判断条件,但是我现在脑子一团浆糊也不想想其他更优解了。。
for(int i=100;i>-1;i--)
{
if(a[i]!=0)
{
max = i;
break;
}
}
第三部分,输出幂次最大项
首先要注意的是a[max]的大小,大于零和小于零,等于正负一和不等于正负一输出不同,要分开。
并且max等于零,等于一,等于其他数的输出也不一样,这里先输出不等于零的情况,其他的情况到后面再输出。
if (a[max]>0&&max!=1&&max!=0) //做一个判断,排除最大幂次为零或一的情况。
{
if(a[max]>1) //系数为一和不为一的情况要分开输出。
{
printf("%dx%d",a[max],max);
}
else
{
printf("x%d",max);
}
}
else if(a[max]<0&&max!=0&&max!=1) //跟上面一样
{
a[max] = abs(a[max]); //这是为了输出为减号而不是负号,这一步可能是不需要的。
if(a[max]>1) //这里a[max]已经被换为正数了,不要惯性思维认为a[max]还是负数做一个负的判断
{
printf("-%dx%d",a[max],max);
}
else if(a[max]==1)
{
printf("-x%d",max);
}
}
第四部分,输出幂次小于max,但又大于1的其他项
这一部分和上面大同小异,只是不用考虑幂次为0或为1,但是还是要考虑系数绝对值是否等于1。
for(int i=max-1;i>1;i--) //幂次比max小,又比1大的遍历循环。
{
if(a[i]>0) //只有系数不为零才能输出。
{
if(a[i]>1)
{
printf("+%dx%d",a[i],i);
}
else
{
printf("+x%d",i);
}
}
else if(a[i]<0)
{
a[i] = abs(a[i]);
if(a[i]>1)
{
printf("-%dx%d",a[i],i);
}
else if(a[i]==1)
{
printf("-x%d",i);
}
}
}
第五部分,输出幂次为一的项
如果这一项是负的,那么它前面一定要有减号,就不用考虑它是不是第一项了,但是如果它是正的,不是第一项的话前面要用加号链接,是第一项的话前面应该没有加号,所以在a[1]>0的情况要再判断一次。
if(a[1]>0) //系数为正的情况。
{
if(max!=1) //不是第一项的情况。
{
if(a[1]>1) //系数为一或为零。
{
printf("+%dx",a[1]);
}
else
{
printf("+x");
}
}
else if (max==1) //a[1]是第一项的情况
{
if(a[1]>1)
{
printf("%dx",a[1]);
}
else
{
printf("x");
}
}
}
else if(a[1]<0)
{
a[1] = abs(a[1]);
if(a[1]>1)
{
printf("-%dx",a[1]);
}
else if (a[1]==1)
{
printf("-x");
}
}
最后一部分,输出幂次为零的项(常数项)
如果常数项不是第一项,则常数项为零时不必要输出它,但是常数项为第一项时,即使为零了也要把它输出。
if(max==0) //常数项为第一项的情况
{
if(a[0]>-1) //这里包含了常数项为零的情况
{
printf("%d",a[0]);
}
else if(a[0]<0)
{
a[0] = abs(a[0]);
printf("-%d",a[0]);
}
}
else if(max!=0) //常数项不是第一项的情况
{
if(a[0]>0) //这里就没包含常数项为零的情况
{
printf("+%d",a[0]);
}
else if(a[0]<0)
{
a[0] = abs(a[0]);
printf("-%d",a[0]);
}
}
return 0;
}
下面时完整版无注释的代码
#include<stdio.h>
#include<math.h>
int main()
{
int x,y,max=0,a[101]={0};
for(int i=0;i<2;i++)
{
do
{
scanf("%d %d",&x,&y);
a[x] += y;
}while(x!=0);
}
for(int i=100;i>-1;i--)
{
if(a[i]!=0)
{
max = i;
break;
}
}
if (a[max]>0&&max!=0&&max!=1)
{
if(a[max]>1)
{
printf("%dx%d",a[max],max);
}
else
{
printf("x%d",max);
}
}
else if(a[max]<0&&max!=0&&max!=1)
{
a[max] = abs(a[max]);
if(a[max]>1)
{
printf("-%dx%d",a[max],max);
}
else if(a[max]==1)
{
printf("-x%d",max);
}
}
for(int i=max-1;i>1;i--)
{
if(a[i]>0)
{
if(a[i]>1)
{
printf("+%dx%d",a[i],i);
}
else
{
printf("+x%d",i);
}
}
else if(a[i]<0)
{
a[i] = abs(a[i]);
if(a[i]>1)
{
printf("-%dx%d",a[i],i);
}
else if(a[i]==1)
{
printf("-x%d",i);
}
}
}
if(a[1]>0)
{
if(max!=1)
{
if(a[1]>1)
{
printf("+%dx",a[1]);
}
else
{
printf("+x");
}
}
else if (max==1)
{
if(a[1]>1)
{
printf("%dx",a[1]);
}
else
{
printf("x");
}
}
}
else if(a[1]<0)
{
a[1] = abs(a[1]);
if(a[1]>1)
{
printf("-%dx",a[1]);
}
else if (a[1]==1)
{
printf("-x");
}
}
if(max==0)
{
if(a[0]>-1)
{
printf("%d",a[0]);
}
else if(a[0]<0)
{
a[0] = abs(a[0]);
printf("-%d",a[0]);
}
}
else if(max!=0)
{
if(a[0]>0)
{
printf("+%d",a[0]);
}
else if(a[0]<0)
{
a[0] = abs(a[0]);
printf("-%d",a[0]);
}
}
return 0;
}
其实这个代码写得确实挺烂,写这篇文章主要是给大家提醒下易错的地方,知道了那些易错点和大致流程大家都能写出更好的代码。