2020-4月数据结构课设--一元多项式的表示及其运算

#include<stdio.h>



#include<stdlib.h>



#include<windows.h>



typedef struct linklist{

    double coef;      //系数

    int expn;     //指数

    struct linklist *next;//指针域

}linklist,*Link;



Link L1,L2,L3; //多项式

int n1,n2;    //多项式长度



//函数声明

void menu();//菜单模式

void creatlist(Link &L,int N);             //创建多项式

int  cmp(Link L1, Link L2);

int  LocateElem(Link p, Link s, Link &q);

Link PolyAdd(Link pa, Link pb);                //多项式相加

Link PolySub(Link pa, Link pb);                //多项式相减

Link Reverse(Link L);                   //多项式逆置

Link PolyMulti(Link pa,Link pb);           //多项式相乘

void Calculate(Link L, double x);         //多项式求值

void Print(Link L);                          //打印多项式

void menu(){

    printf("|------------------------------------------------------------------------------------|\n");

    printf("|\t\t\t临沂大学2019计科一班一组多项式的表示及操作\t             |\n");

    printf("|\t 团队成员                        *           操作菜单                   *    |\n");

    printf("|     学号\t姓名\t                 *                                      *    |\n");

    printf("|201909150101  田树林                    *     +  : ->多项式相加                *    |\n");

    printf("|201909150105  高天                      *     -  : ->多项式相减                *    |\n");

    printf("|201909150115  王得玉                    *     *  : ->多项式相乘                *    |\n");

    printf("|201909150123  刘一萱                    *     /  : ->多项式相除(该功能还未开放)*    |\n");

    printf("|201909150130  孙凯民                    *     '  : ->多项式求导(该功能还未开放)*    |\n");

    printf("|------------------------------------------------------------------------------------|\n");

    printf("请您根据以下指令进行操作\n\n");

    printf("请输入第一个多项式的项数: \n");

    scanf("%d",&n1);

    creatlist(L1,n1);

    printf("第一个多项式为: P1(X)=");

    Print(L1);

    printf("请输入第二个多项式的项数: \n");

    scanf("%d",&n2);

    creatlist(L2,n2);

    printf("第二个多项式为: P2(X)=");

    Print(L2);

}



void creatlist(Link &L,int n){

    Link s,q;

    L=(Link)malloc(sizeof(linklist));

    L->next=NULL;

    for(int i=0;i<n;i++)

    {

        s=(Link)malloc(sizeof(linklist));



        printf("请输入多项式的系数和指数:\n");



        scanf("%lf %d", &s->coef, &s->expn);



        if(!LocateElem(L, s, q)){  //若没有相同指数项,则链入

            s->next = q->next;

            q->next = s;

        }

        else{                 //若有相同指数项,则系数相加

            q->coef += s->coef;

        }

    }



}



void Print(Link L){

    Link s;

    s = L->next;

    while(s)

    {

        printf(" %.2lf X^%d", s->coef, s->expn);

        s = s->next;

        if(s!=NULL)

            if(s->coef>=0) printf(" +");

        //若下一项系数为正,则打印'+',否则不打印

    }

    printf("\n");

}



int cmp(Link L1, Link L2)

{

    if (L1->expn<L2->expn) return  -1;

    else if(L2->expn == L1->expn) return  0;

    else return 1;

}



int LocateElem(Link p, Link s, Link &q){



    Link p1 = p->next;

    Link p2 = p;

    while(p1){

        if(s->expn > p1->expn){

            p1 = p1->next;

            p2 = p2->next;

        }

        else if(s->expn == p1->expn){

            q = p1;

            return 1;

        }

        else{

            q = p2;

            return 0;

        }

    }

    if(!p1){

        q = p2;

        return 0;

    }

}



Link PolyAdd(Link pa, Link pb){

    Link head, L1, L2, s, p;

    double sum;

    L1 = pa->next;

    L2 = pb->next;

    head=(Link)malloc(sizeof(linklist)); //新多项式的头结点

    p = head;  //p指向新多项式的头结点

    while(L1&&L2){

        switch(cmp(L1, L2))

        {

            case -1:// //若指数:L1<L2,则将p所指结点链入头结点为head的链表中,且L1向后遍历

                s = (Link)malloc(sizeof(linklist));

                s->coef = L1->coef;

                s->expn = L1->expn;

                p->next = s;

                p = s;

                L1 = L1->next;

                break;

            case 0://若比较两项的指数相等,则将两项系数相加后得到的项放入头结点为head的链表中 ,且L1,L2同时向后遍历

                sum = L1->coef+L2->coef;

                if(sum!=0.0)//若两项系数相加为0,则不放入头结点为head的链表中

                {

                    s = (Link)malloc(sizeof(linklist));

                    s->coef = sum;

                    s->expn = L1->expn;

                    p->next = s;

                    p = s;

                }

                L1 = L1->next;

                L2 = L2->next;

                break;

            case 1://若指数:L2<L1,则将L2所指结点链入头结点为head的链表中,且L2向后遍历

                s = (Link)malloc(sizeof(linklist));

                s->coef = L2->coef;

                s->expn = L2->expn;

                p->next = s;

                p = s;

                L2 = L2->next;

                break;

        }

    }

    p->next=L1?L1:L2;//链入pa或pb的剩余项

    return head;//返回新多项式的头指针

}



Link PolySub(Link pa, Link pb)

{

    Link head, L1, L2, s, p;

    double sum;

    head=(Link)malloc(sizeof(linklist));

    p = head;

    L1 = pa->next;

    L2 = pb->next;



    while(L2){// 将pb中每一项的系数变为负

        L2->coef=0-L2->coef;

        L2=L2->next;

    }

    L2=pb->next;

    while(L1&&L2){

        switch(cmp(L1, L2))

        {

            case -1:

                s = (Link)malloc(sizeof(linklist));

                s->coef = L1->coef;

                s->expn = L1->expn;

                p->next = s;

                p = s;

                L1 = L1->next;

                break;

            case 0:

                sum = L1->coef-L2->coef;

                if(sum!=0.0)

                {

                    s = (Link)malloc(sizeof(linklist));

                    s->coef = sum;

                    s->expn = L1->expn;

                    p->next = s;

                    p = s;

                }

                L1 = L1->next;

                L2 = L2->next;

                break;

            case 1:

                s = (Link)malloc(sizeof(linklist));

                s->coef = L2->coef;

                s->expn = L2->expn;

                p->next = s;

                p = s;

                L2 =L2->next;

                break;

        }

    }

    p->next=L1?L1:L2;

    return head;

}



Link Reverse(Link L)

{

    Link head=L;

    Link q1,q2;

    q2=head->next;

    head->next=NULL;//断开头结点与第一个结点

    while(q2)

    {

        q1=q2;

        q2=q2->next;

        q1->next=head->next; //头插

        head->next=q1;

    }

    return head;//返回链表逆置后的头结点

}



Link PolyMulti(Link pa,Link pb){

    Link L1,L2,L3,s,head;

    int k,maxExpn,minExpn;

    double coef;



    head=(Link)malloc(sizeof(linklist));//头结点

    head->next=NULL;



    if(pa->next!=NULL&&pb->next!=NULL){

        minExpn=pa->next->expn+pb->next->expn; //minExpn为两个多项式中指数和的最小值

        pa=Reverse(pa);//将A降幂排列

        pb=Reverse(pb);//将B降幂排列

        maxExpn=pa->next->expn+pb->next->expn; //maxExpn为两个多项式中指数和的最大值

    }

    else{

        return head;

    }

    L3=head;

    pb=Reverse(pb);//将B升幂排列



    for(k = maxExpn;k>=minExpn;k--){ //多项式的乘积指数范围为:minExpn~maxExpn

        //根据两项的指数和使每一次循环都得到新多项式中一项

        L1 = pa->next;

        while(L1 !=NULL&&L1->expn>k){  //找到pa的位置

            L1 = L1->next;

        }

        L2 = pb->next;

        while(L2!=NULL&&L1!=NULL&&L1->expn+L2->expn<k){//如果指数和和小于k,pb后移结点

            L2 = L2->next;

        }

        coef=0.0;

        while(L1!=NULL&&L2!=NULL){

            if(L1->expn+L2->expn==k){ //如果指数和等于k,系数和累加,且pa,pb均后移结点

                coef+=L1->coef*L2->coef;

                L1=L1->next;

                L2=L2->next;

            }

            else if(L1->expn+L2->expn>k){//如果指数和大于k,pb后移结点

                L1 = L1->next;

            }

            else{//如果指数和和小于k,pb后移结点

                L2 = L2->next;

            }

        }

        if(coef!=0.0){

            //如果系数和不为0,则生成新结点,将系数和指数赋给新结点后插入到新多项式中

            s=(Link)malloc(sizeof(linklist));

            s->coef=coef;

            s->expn=k;

            s->next=L3->next;

            L3->next=s;

            L3=s;

        }

    }

    pb = Reverse(pb);

    head=Reverse(head);

    return head;   //返回新多项式的头结点

}



void Calculate(Link L, double x){

    Link q=L->next;

    double sum;

    double result=0;//求的结果

    while(q){

        sum=1.0;

        for(int i=1;i<=q->expn;i++){//先求每一项的 X^expn 的值

            sum=sum*x;

        }

        result+=sum*q->coef; //再使系数与sum相乘后求每一项的值,最后累加

        q=q->next;

    }

    printf("将X的值代入多项式中计算的结果为:%.4f\n",result);

}



int main()

{

    system("color 2F");



    menu() ;//实现系统桌面模拟化;



    //以下是对多项式的操作命令

    printf("请输入要选择的运算{+ , - , * , / , dy/dx }\n");

    char ch1;

    getchar();

    scanf("%c",&ch1);

    getchar();

    switch(ch1){

        case '+':{

            printf("两个一元多项式相加:  P1(X)+P2(X) = ");

            L3=PolyAdd(L1, L2);

            Print(L3);

        }break;

        case '-':{

            printf("两个一元多项式相减:  P1(X)-P2(X) = ");

            L3=PolySub(L1, L2);

            Print(L3);

        }break;

        case '*':{

            printf("两个一元多项式相乘: P1(X)*P2(X) = ");

            L3=PolyMulti(L1, L2);

            Print(L3);

        }break;

        case '/':{

            printf("该功能还在升级;未开放!");

        }return 0;

        case 'dy/dx':{

            printf("该功能还在升级;未开放!");

        }return 0;

        default:printf("You entered the wrong command %c !",ch1);return 0;

    }



//对多项式的带入求值

    char ch2;

    printf("\n是否代入X进行求值(Y/N): ");

    ch2=getchar();

    getchar();

    switch(ch2){

        case 'Y':{

            double x;

            printf("\n请输入多项式中X的值:");

            scanf("%lf",&x);

            Calculate(L3,x);

            break;

        }

        case 'N':break;

        default:printf("You entered the wrong command %c !",ch2);

    }

    return 0;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值