【数据结构-C语言】一元多项式计算器

本文介绍了一种使用单链表存储稀疏一元多项式的方法,并详细阐述了解决多项式相乘及从降幂转为升幂输出的技术方案。通过工具函数实现多项式相乘,利用线性表辅助完成升幂排序。
#include <stdio.h>
#include <stdlib.h>

typedef struct PolyNode *Polynomial;//存储结构为:带头节点的单链表
struct PolyNode {
    int coef;//多项式系数
    int expon;//多项式指数
    Polynomial next;//指向下一个节点
};
typedef Polynomial PList;

typedef struct array{//建立一个线性表,用来作为中转将单链表逆序
    int *data;//存单链表中多项式的数据,下标表示多项式的指数
    int size;//线性表的大小
    int length;//线性表的长度
}Array;

PList PolyRead();//读入一个多项式
Array CreatArray();//初始化一个线性表
PList IncreasingPower(PList p);//将一个降幂的多项式升幂排序
PList Add(PList p1,PList p2);//两个多项式相加
PList Sub(PList p1,PList p2);//两个多项式相减
PList Mult(PList p1,PList p2);//两个多项式相乘
void PrintPoly(PList p);//输出多项式
void FreeLink(PList p);//清空链表
PList MultTool(PList p1,PList p2);//乘法所需用到的一个工具,用来实现一个多项式中的某一项与另一个多项式做乘法运算

int main()
{
    printf("欢迎来到一元多项式计算器\n");
    printf("请输入您要进行的操作(如+、-、*):\n");
    char ope;
    scanf("%c",&ope);//输入操作符(如+、-、*)
    PList p1,p2,pap,psp,pmp;
    p1=PolyRead();//创建第一个多项式
	p2=PolyRead();//创建第二个多项式

    switch (ope){
        case '+':
            printf("两个多项式相加的结果是:\n");
            pap=Add(p1,p2);
            printf("降幂:");
            PrintPoly(pap);
            pap=IncreasingPower(pap);//将一个降幂的多项式升幂排序
            printf("升幂:");
            PrintPoly(pap);
            break;
        case '-':
            printf("两个多项式相减的结果是:\n");
            psp=Sub(p1,p2);
            printf("降幂:");
            PrintPoly(psp);
            psp=IncreasingPower(psp);//将一个降幂的多项式升幂排序
            printf("升幂:");
            PrintPoly(psp);
            break;
        case '*':
            printf("两个多项式相乘的结果是:\n");
            pmp=Mult(p1,p2);
            printf("降幂:");
            PrintPoly(pmp);
            pmp=IncreasingPower(pmp);//将一个降幂的多项式升幂排序
            printf("升幂:");
            PrintPoly(pmp);
            break;
        default :
            printf("输入错误,请重新输入。\n注意:只能输入+、-、*\n");
    }
    return 0;
}

PList PolyRead(){
    PList p,r,t;
    p=(PList)malloc(sizeof(struct PolyNode));
    r=p;
    int c,e;
    printf("只需按降幂的顺序输入多项式的系数和指数即可\n");
    printf("若要结束输入,请回车后按“Ctrl+Z”键,再次回车即可结束\n");
    while(scanf("%d%d",&c,&e)!=EOF){
        t=(PList)malloc(sizeof(struct PolyNode));
        t->coef=c;
        t->expon=e;
        r->next=t;
        r=t;
    }
    r->next=NULL;
    return p;
}

Array CreatArray(){
    Array arr;
    arr.size=220;
    arr.length=0;
    arr.data=(int *)malloc(sizeof(int)*arr.size);
    //将线性表中的元素初始化为0
    for(int i=0;i<arr.size;i++) arr.data[i]=0; 
    return arr;
}

PList IncreasingPower(PList p){
    Array arr=CreatArray();
    PList pi=(PList)malloc(sizeof(struct PolyNode));
    PList t=p->next,r=pi,s;
    //将单链表中的元素转移到线性表中
    while(t){
        arr.data[t->expon]=t->coef;
        if(arr.length < t->expon) arr.length=t->expon;
        t=t->next;
    }
    FreeLink(p);//释放存储降幂排序多项式的单链表
    arr.length++;
    //利用线性表的有序性,将已经升幂排好序的多项式重新转到线性表中
    for(int i=0;i<arr.length;++i){
        if(arr.data[i]==0) continue;
        s=(PList)malloc(sizeof(struct PolyNode));
        s->expon=i;
        s->coef=arr.data[i];
        r->next=s;
        r=s;
    }
    r->next=NULL;
    free(arr.data);//释放线性表中的元素所占用的空间
    return pi;
}

PList Mult(PList p1,PList p2){
    PList t1=p1->next,t2=p2->next,pp,t;
    pp=(PList)malloc(sizeof(struct PolyNode));
    pp->next=NULL;
    while(t1){
        t=MultTool(t1,t2);//将t1中的每一项乘以t2中的所有项,存储到t中
        pp=Add(t,pp);//将t加到pp中
        FreeLink(t);//释放t
        t1=t1->next;
    }
    return pp;
}

PList Add(PList p1,PList p2){
    PList t1=p1->next,t2=p2->next,ps,r,t;
    ps=(PList)malloc(sizeof(struct PolyNode));
r=ps;

    //t1和t2都不为空时,通过比较,合并到单链表中
    while(t1 && t2){
        t=(PList)malloc(sizeof(struct PolyNode));
        if(t1->expon > t2->expon){
            t->coef=t1->coef;
            t->expon=t1->expon;
            r->next=t;
            r=t;
            t1=t1->next;
        }else if(t1->expon < t2->expon){
            t->coef=t2->coef;
            t->expon=t2->expon;
            r->next=t;
            r=t;
            t2=t2->next;
        }else{
            int sum=t1->coef+t2->coef;
			//当合并同类项不为0时,存入单链表中
            if(sum){ 
                t->coef=sum;
                t->expon=t1->expon;
                r->next=t;
                r=t;
            }
                t1=t1->next;
                t2=t2->next;

        }

}

    //当t2为空时,将t1中剩下的元素放到单链表中
    while(t1){
        t=(PList)malloc(sizeof(struct PolyNode));
        t->coef=t1->coef;
        t->expon=t1->expon;
        r->next=t;
        r=t;
        t1=t1->next;
}

    //当t1为空时,将t2中剩下的元素放到单链表中
    while(t2){
        t=(PList)malloc(sizeof(struct PolyNode));
        t->coef=t2->coef;
        t->expon=t2->expon;
        r->next=t;
        r=t;
        t2=t2->next;
    }
    r->next=NULL;
    return ps;
}

PList Sub(PList p1,PList p2){
    PList trans=p2->next,ps;
    //将t2中的系数求反
    while(trans){
        trans->coef=0-trans->coef;
        trans=trans->next;
    }
    ps=Add(p1,p2);
    return ps;
}

void PrintPoly(PList p){
    PList t=p->next;
    if(!t){
        printf("0 0");//零多项式输出0 0
    } else {
        while(t){
            //只有项的系数不为0时才能输出
            if(t->coef != 0){
                //当指数为0时,只输出系数
                if(t->expon==0) printf("%d",t->coef);
                //系数和指数都为1,输出x
                else if(t->coef == 1 && t->expon == 1) printf("x");
                //系数为-1,指数为1,输出-x
                else if(t->coef == -1 && t->expon == 1) printf("-x");
                //系数为1,指数不为1,不输出系数
                else if(t->coef == 1 && t->expon != 1) printf("x^%d",t->expon);
                //系数为-1,但是指数不为1,系数只输出-
                else if(t->coef == -1 && t->expon != 1) printf("-x^%d",t->expon);
                //系数不是1或-1,指数为1,不输出指数
                else if((t->coef != 1 || t->coef != -1) && t->expon == 1)  printf("%dx",t->coef);
                //系数不是1或-1,指数不为1,系数和指数都输出
                else if((t->coef != 1 || t->coef != -1) && t->expon != 1)  printf("%dx^%d",t->coef,t->expon);

                //如果有下一项且下一项的系数为大于0的数,则输出+
                if(t->next && t->next->coef>0) printf("+");
                t=t->next;
            }
        }
    }
    printf("\n");
}

void FreeLink(PList p){
    PList r=p->next,s;
    while(r){
        s=r->next;
        free(r);
        r=s;
    }
    free(p);
}

PList MultTool(PList p1,PList p2){
    PList t1=p1,t2=p2,t,r,temp;
    t=(PList)malloc(sizeof(struct PolyNode));
r=t;

    while(t2){
        temp=(PList)malloc(sizeof(struct PolyNode));
        temp->coef=t1->coef*t2->coef;
        temp->expon=t1->expon+t2->expon;
        r->next=temp;
        r=temp;
        t2=t2->next;
}

    r->next=NULL;
    return t;
}


在设计一元多项式计算器时,考虑到多项式可能较为稀疏,所以采用单链表的存储方式。

在设计中遇到的困难:如何将两个多项式相乘、如何将降幂的多项式转换为升幂顺序的多项式并输出。

解决方案:对于多项式相乘,利用一个工具函数,将多项式的某一项与另一个多项式的每一项相乘并返回,将返回的多项式相加便可得到结果;对于逆序输出,利用一个线性表,将单链表中的元素存到一个线性表中,多项式的指数为线性表的下标,因此存入时,便已经按升幂的顺序排好了,只需将线性表中的元素再次存回单链表即可得到升幂的结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值