1010 一元多项式求导

展示了如何使用C++编写程序,以链表形式处理输入的多项式,计算并输出导数,同时处理常数项和合并同类项的特殊情况。
摘要由CSDN通过智能技术生成

设计函数求一元多项式的导数。(注: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多项式;
*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值