设计函数求一元多项式的导数。(注:xn(n为整数)的一阶导数为nxn−1。)
输入格式:
以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数)。数字间以空格分隔。
输出格式:
以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是 0,但是表示为 0 0
。
输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
/*
本题相对是比较简单的题型,这里题目只给了多项式,没有给多项式个数
这里需要用到链表进行存储。
题目给定的数是按照指数递降给的,用数组操作其实更方便,那么我们可以
对链表元素进行计数,在转移存储到数组中。
幂函数求导:得到系数是原函数的系数*指数;指数则减一
这里注意多项式含0的情况:
case 1:2 0 //这种是常数,求导后为0,不输出;
case 2:0 0 //这种也算是常数0,求导后为0,不算是0多项式,同case 1不输出;
case 3:0 3 //这种求导后为 0 2,但系数为0,应该算作是零多项式(指数不为0),输出0 0
若case1、2只有一个常数,求导后是不输出还是输出0 0呢;
然后就是输入标志,怎么样读入数据,什么时候结束输入;
输入一定是成对的,末尾以回车结束;这里求导可以直接当时处理而不存储。
因为都是顺序输入,不需要进行排序之类的。这里给的数据第一个一定是整数
格式:
数 空格 数 空格 数 空格 数 回车
按照这样进行读入就可以了。
补充:
注意如果最后一项是常数项时,不太好设置空格输出的条件,那么这里还是考虑用链表存储,
将求导后的数据存入链表再进行输出就比较方便;
这里漏掉了指数相同的情况,若指数相同,应该合并同类项,并且当系数互为相反数时,
相加之后系数为0,指数不为0,比如0 2,这种算是0多项式,只需要输出一次.
然后数组中出现了多次零多项式,应该只输出一次;合并为一个0多项式;
最后合并同类项改到
*/
#include<iostream>
#include<cstdlib>
using namespace std;
struct Node{
int A;
int B;
struct Node* Next;
};
int main(){
/*
int a,b; //a表示当前输入的系数,b表示输入的指数;
char c=' '; //c读取数字之间的空格及最后的回车来结束;
int x; //作为输入变量;
int flag=1; //用flag来标志当前的数是系数还是指数;为1表示系数,为0表示指数;
while(c!='\n'){ //读到最后的回车就结束输入;
cin>>x;
if(flag==1){
a=x;
flag=0; //这里读入a之后注意切换flag状态,让其读入b;
}
else if(flag==0){
b=x; //此时若是b则表示这一对ab已经找完了,可以进行求导了;
a=a*b;
b=b-1; //这两步是求导,系数乘指数,指数减一;
//输出求导结果;
if(a!=0){
cout<<a<<" "<<b; //此时输出的情况为ab都不为0的情况;a=a*b,ab都不为0,a就不会为0;
}
else if(a==0&&b!=-1){ //零多项式的情况;
cout<<'0'<<" "<<'0'; //这里b!=-1排除了常数项指数为0的情况,
}
else{
//常数不必输出;
}
flag=1; //这里读入b之后要切换,读下一个a;
}
c=getchar();
if(c!='\n'&&flag==1){ //flag为1表示当前的x为指数b,这时候可输出该项后空格;
cout<<' '; //这里单独输出多项式之间的空格,最后换行时不输出空格;
}
}
//这里不需要补输出,因为在读入回车前,所有的数据都是读入了的;
*/
int count=0; //记录项数;
int a,b; //a表示当前读入的系数,b表示当前读入的指数;
char c; //c读取数字之间的空格和末尾回车;
int x; //x作为读数的变量;
int flag=1; //flag标志指示x代表系数还是指数;为1表示系数,为0表示指数;
int head=1; //标志链表第一个节点,我一般不用带头节点的的链表;
struct Node* p=NULL;
struct Node* List=NULL;
c=' ';
while(c!='\n'){
cin>>x; //读入数据;
if(flag==1){
a=x; //x设置为系数;
flag=0; //读取b;
}
else if(flag==0){
b=x; //x设置为指数;
a=a*b; //直接求导;再将求导后的数存入链表;
b--;
flag=1; //读取下一个a;
//创建导数链表;
if(head){
//创建第一个结点;
head=0; //第一个结点创建,标志失效;
List=(struct Node*)malloc(sizeof(struct Node)); //申请一个结点;
p=List;
p->A=a;
p->B=b;
p->Next=NULL;
count++;
}
else{
//后继结点;
p->Next=(struct Node*)malloc(sizeof(struct Node)); //申请下一个结点;
p=p->Next; //指向下一个结点;
p->A=a;
p->B=b;
p->Next=NULL;
count++;
}
}
c=getchar(); //读取空格;
}
//转为数组存放;
struct Node Data[count];
int i=0;
for(struct Node* q=List;q;q=q->Next){
//常数项不必存放;
if(q->B!=-1){ //求导后指数为1,表明原指数为0,即常数,不必保存;
Data[i].A=q->A;
Data[i].B=q->B;
Data[i].Next=NULL;
i++;
}
}
//检查0多项式;
int zero=0; //记录0多项式个数;
for(int j=0;j<i;j++){
if(Data[j].A==0&&Data[j].B!=-1){
zero++;
}
}
//零多项式单独合并;
int save=0; //保留一组0多项式;save为1表示找到第一个0多项式;为0表示没找到;
if(zero>1){
for(int j=0;j<i;j++){
if(save==0){ //找第一个0多项式;
if(Data[j].A==0&&Data[j].B!=-1){
save=1;
}
}
else if(save==1){
if(Data[j].A==0&&Data[j].B!=-1){ //之后的零多项式不用输出;
Data[j].B=-1;
}
}
}
}
//合并同类项;
for(int j=0;j<i;j++){
for(int k=j+1;k<i;k++){
if(Data[j].B==Data[k].B){
Data[j].A=Data[j].A+Data[k].A;
Data[k].A=0;
Data[k].B=-1; //标记为常数项不用输出;
}
}
}
//整理数组(输出时会出现空格,于是整理再进行输出);
struct Node Sort[count];
int number=0;
for(int j=0;j<i;j++){
if(Data[j].B!=-1){
Sort[number].A=Data[j].A;
Sort[number].B=Data[j].B;
number++;
}
}
//输出数组;
for(int j=0;j<number;j++){
//输出非0多项式;
if(Sort[j].A){
cout<<Sort[j].A<<" "<<Sort[j].B;
}
else{
//输出唯一一个0多项式;
cout<<"0 0";
}
if(j<number-1){
cout<<' ';
}
}
//补充:仅有一个常数求导:
if(count==1&&number==0){
//count表示有一个多项式number为0表示以常数形式不输出;
cout<<"0 0";
}
/*
//输出数组中数据;
for(int j=0;j<i;j++){
//输出非0多项式;
if(Data[j].A!=0){
cout<<Data[j].A<<' '<<Data[j].B;
}
else{ //输出0多项式;
if(Data[j].B!=-1){ //这里-1标记的常数不用输出;
cout<<"0 0";
}
}
//输出多项式之间空格;
if(j<i-1){
cout<<" ";
}
}*/
/*
//输出导数链表;
for(struct Node* q=List;q->Next;q=q->Next){
//输出非常数多项式;
if(q->A!=0){
cout<<q->A<<" "<<q->B; //逐项输出;
}
else if(q->A==0&&q->B!=-1){
cout<<"0 0";
}
//输出多项式之间的空格;
if(q->Next){ //如果当前项有下一项;即不是最后一项;
//检查下一项是否是常数项;
if((q->Next)->B==-1){
//若是常数则不输出;然后再看下一项的下一项是否能够输出;
if(((q->Next)->Next)->B!=-1){ //能够输出则输出之间空格;
cout<<" "; //输出空格;
}
}
else{ //若不是常数项则正常输出空格;
cout<<" ";
}
}
}*/
return 0;
}
/*
解题反思:本题耗时比较长,但是思路清晰,中间一些细节需要主要。第一个思路在线处理,
输入一项输出一项,但是如果有指数相同的就不行,会多次输出,末尾空格也不好设置,第一
次没有想到递降存在相同,那么自然也没想到合并同类项;这里我把合并后的位置设置为常数
求导后的形式(指数为-1),但是这里有一个特殊,0 3,求导后是看作常数还是0多项式,应该
是0多项式,因为指数不为0;但是只有一个常数的时候,求导后不输出看起来不太对,那么应该
当只有一个常数时,求导后应该输出0多项式;
*/