多项式加法(链表)

声明:图片及内容基于https://www.bilibili.com/video/av78358478

题目描述

输入两个多项式并将其合并

具体实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h> 
#include<stdlib.h>
#include<string.h>
typedef struct polynomial
{
    int coefficient;//系数
    int exp;//指数
    struct polynomial* next;
}*Link, Node;
void clearLink(Link head);
void inputPoly(Link head);//用于从控制台读入链表的函数
void print(Link head);//打印链表用的函数
bool insert(Link head, int coefficient, int exp);//向链表插入一个元素的函数
void combin2List(Link heada, Link headb, Link headab);//合并两个链表

int main()
{

    Link headA, headB;//两个多项式的头指针
    Link headAB;//合并后的多项式的头指针

    /*链表的初始化*/
    headA = (Link)malloc(sizeof(Node));
    headA->next = NULL;
    headB = (Link)malloc(sizeof(Node));
    headB->next = NULL;
    headAB = (Link)malloc(sizeof(Node));
    headAB->next = NULL;

    printf("请输入第一个多项式的系数和指数,以(0 0)结束:\n");
    inputPoly(headA);
    printf("第一个");
    print(headA);
    printf("请输入第二个多项式的系数和指数,以(0 0)结束:\n");
    inputPoly(headB);
    printf("第二个");
    print(headB);

    combin2List(headA, headB, headAB);
    printf("合并后");
    print(headAB);
    clearLink(headA);
    clearLink(headB);
    clearLink(headAB);
    return 0;
}


/**输入二项式数据的函数*/
/*这个函数用来输入二项式,给用户合适的提示,读入用户输入的系数和指数。
调用函数insert,将用户输入的二项式的一项插入到链表中去。*/
void inputPoly(Link head)
{
    int coefficient, exp;//系数和指数
    printf("请输入系数和指数(如:\"2 3\"表示2x^3):");
    scanf("%d %d", &coefficient, &exp);
    while (coefficient != 0 || exp != 0)//连续输入多个系数和指数
    {
        insert(head, coefficient, exp);//调函数输入多项式
        printf("请输入系数和指数:");
        scanf("%d %d", &coefficient, &exp);
    }
}

/**向多项式链表中插入元素的函数
int coefficient 一个多项式项的系数
int exp 一个多项式项的幂
*/
bool insert(Link head, int coefficient, int exp)
{
    Link node;  //node指针指向新创建的节点
    Link q, p;   //q,p两个节点一前一后

    //创建一个新结点
    //.....
    node = (Link)malloc(sizeof(Node));
    node->coefficient = coefficient;
    node->exp = exp;
    node->next = NULL;

    if (head->next == NULL)//空表,插第1个
    {
        //......
        head->next = node;
        node->next = NULL;
    }
    else
    {
        q = head;
        p = head->next;
        while (p != NULL) {//循环访问链表中的所有节点

            //如果node节点的指数比p节点的指数大,则插在p的前面,完成插入后,提前退出
            if (node->exp > p->exp) {
                node->next = p;
                q->next = node;
                return true;
            }
            //如果node节点的指数和p节点的指数相等,则合并这个多项式节点,提前退出
            else if (node->exp == p->exp) {
                p->coefficient += node->coefficient;
                return true;
            }
            //如果node节点的指数比p节点的指数小,继续向后移动指针(依然保持p,q一前一后)
            else {
                q = p;
                p = p->next;
            }
        }
        //如果退出循环是当前指针p移动到链表结尾,则说明之前没有插入,那么当前node节点的指数值是最大值,此时插在链表的最后面
        q->next = node;
        node->next = NULL;
    }
    return true;
}



/**
打印多项式链表的函数
*/
/*
① 通过指针访问链表
② 多重条件语句嵌套
③ 数字转换为字符串函数itoa
④ 标志是否为第一个节点的flag的设置
⑤ 字符串连接函数strcat
⑥ 字符串清空函数memset。memset(item,0,20);清空长20的字符串item
请补充代码实现。
*/
void print(Link head)
{
    Link p; //指向链表要输出的结点
    printf("多项式如下:\n");
    p = head->next;

    if (p == NULL)
    {
        printf("多项式为空\n");
        return;
    }
    // 不是空表
    char item[20] = "";//要打印的当前多项式的一项
    char number[7] = "";//暂时存放系数转换成的字符串

    bool isFirstItem = true;//标志是否为第一个节点的flag
    //打印节点
    do
    {
        if (p->coefficient == 0) {
            p = p->next;//指向下个结点
            continue;
        }
        memset(item, 0, 20);//清空字符串item
        //如果是第一项,不要打+号
        //如果不是第一项,且系数为正数,要打加号
        if (!isFirstItem && p->coefficient > 0) {
            strcat(item, "+");
        }
        //如果系数为负数,系数自身带有符号

        //如果系数为1,不用打系数
        //系数为-1打印负号
        if (p->coefficient == 1) {}
        else if ((p->coefficient == -1)) {
            strcat(item, "-");
        }
        //如果系数不为1或-1,打印系数
        else
            strcat(item, _itoa(p->coefficient, number, 10));
        //如果指数为0,直接打系数不用打x^和指数
        //如果系数是-1或1,需要打1出来,不能只打符号
        if (p->exp == 0) {
            if (p->coefficient == 1 || p->coefficient == -1) strcat(item, "1");
        }
        else {                        //指数不为0
            strcat(item, "x");        //打印x
            if (p->exp != 1) {            //如果指数为1,不打指数,否则打指数
                strcat(item, "^");
                strcat(item, _itoa(p->exp, number, 10));
            }
        }
        printf("%s", item);//打印当前节点代表的项
        p = p->next;//指向下个结点
        isFirstItem = false;//flag标志不是第一项了
    } while (p != NULL);
    printf("\n");
    return;
}

/**
合并两个有序链表a,b到链表ab
heada.headb,headab分别为链表a,b,ab的头指针
*/
void combin2List(Link heada, Link headb, Link headab)
{
    Link pa, pb;//指向a,b链表和ab的指针
    pa = heada->next;
    pb = headb->next;

    while (pa != NULL && pb != NULL)//a,b链表都没有没有访问完毕
    {
        //如果指数a>指数b,a节点插入ab链表,a指针后移
        if (pa->exp > pb->exp) {
            insert(headab, pa->coefficient, pa->exp);
            pa = pa->next;
        }
        //如果指数a<指数b,b节点插入ab链表,b指针后移
        else if (pa->exp < pb->exp) {
            insert(headab, pb->coefficient, pb->exp);
            pb = pb->next;
        }
        //如果指数a==指数b,a、b系数相加,插入ab链表,a、b指针后移
        else {
            int coefficient = pa->coefficient + pb->coefficient;
            insert(headab, coefficient, pa->exp);
            pa = pa->next;
            pb = pb->next;
        }
        //......

    }
    //如果a、b链表还有尾巴,将它加到ab链表后面
    while (pa != NULL)
    {
        insert(headab, pa->coefficient, pa->exp);
        pa = pa->next;
    }
    while (pb != NULL)
    {
        insert(headab, pb->coefficient, pb->exp);
        pb = pb->next;
    }
    return;
}
void clearLink(Link head) {
    if (head == NULL) return;
    Link p = head;
    while (head) {
        p = head->next;
        free(head);
        head = p;
    }
    return;
}

 测试用例1:
请输入第一个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):1 1
请输入系数和指数:-1 1
请输入系数和指数:2 2
请输入系数和指数:0 0
第一个多项式如下:
2x^2
请输入第二个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):-2 2
请输入系数和指数:2 3
请输入系数和指数:4 5
请输入系数和指数:0 0
第二个多项式如下:
4x^5+2x^3-2x^2
合并后多项式如下:
4x^5+2x^3

 

测试用例2:
请输入第一个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):4 2
请输入系数和指数:-3 3
请输入系数和指数:-1 1
请输入系数和指数:2 0
请输入系数和指数:0 0
第一个多项式如下:
-3x^3+4x^2-x+2
请输入第二个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):4 5
请输入系数和指数:3 3
请输入系数和指数:-3 1
请输入系数和指数:0 0
第二个多项式如下:
4x^5+3x^3-3x
合并后多项式如下:
4x^5+4x^2-4x+2

 

测试用例3:
请输入第一个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):3 5
请输入系数和指数:3 4
请输入系数和指数:-3 0
请输入系数和指数:1 4
请输入系数和指数:0 0
第一个多项式如下:
3x^5+4x^4-3
请输入第二个多项式的系数和指数,以(0 0)结束:
请输入系数和指数(如:"2 3"表示2x^3):-3 5
请输入系数和指数:7 1
请输入系数和指数:2 4
请输入系数和指数:3 0
请输入系数和指数:0 0
第二个多项式如下:
-3x^5+2x^4+7x+3
合并后多项式如下:
6x^4+7x

posted @ 2021-03-10 00:09  gonghr  阅读(386)  评论(0)    收藏  举报