PTA 1002 A+B for Polynomialsde的链表实现

题目:

This time, you are supposed to find A+B where A and B are two polynomials.
Input Specification:

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:

K N​1​​ a​N​1​​​​ N​2​​ a​N​2​​​​ … N​K​​ a​N​K​​​​

where K is the number of nonzero terms in the polynomial, N​i​​ and a​N​i​​​​ (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤N​K​​<⋯<N​2​​<N​1​​≤1000.
Output Specification:

For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.
Sample Input:

2 1 2.4 0 3.2
2 2 1.5 1 0.5

Sample Output:

3 2 1.5 1 2.9 0 3.2

分析:

实际上就是求一元N次多项式的和,本题给出了次数的限制(0≤N​K​​<⋯<N​2​​<N​1​​≤1000.),因此用一个元素个数大于1000的数组可以很简单的实现。
因为最近刚刚开始学链表,所以尝试用链表来做这道题,就是代码有点长,应该还可以短很多。

代码:

//
// Created by dgm on 19-2-25.
//
#include <iostream>
#include <cmath>
#include<iomanip>
using namespace std;
typedef struct ElemType{
    float E;
    int N;
}ElemType;
typedef struct ListNode{
    ListNode()
    :next(NULL)
    {}
    ElemType data;
    ListNode* next;
    unsigned int Length=0;
}*Node;
void Init_List(Node&L,int n)
{
    float E;
    int N;
    L=new ListNode();
    auto p=L;
    for(int i=0;i<n;i++)
    {
        cin>>N>>E;
        Node temp=new ListNode();
        temp->data.E=E;
        temp->data.N=N;
        p->next=temp;       //p始终指向L尾部
        p=p->next;          //尾插法
        L->Length++;
    }
}
void Print_List(Node L)
{
    cout<<L->Length;
    //if(!L->Length)return;
    auto p=L->next;
    while(p){
        cout<<" "<<p->data.N<<" "<< setiosflags(ios::fixed) << setprecision(1) <<p->data.E;
        p=p->next;
    }
}

void Add_List(Node&La,Node Lb)
{

    auto pa=La->next;           //pa指向A中当前元素
    auto pb=Lb->next;           //pb指向B中当前元素
    Node preva=La;              //pa的前驱
    La->Length+=Lb->Length;     //假定和的项数等于
    while(pa&&pb)               //链表A和链表B项数之和
    {                           //之后再根据A,B各项的合并情况调整
        if(pa->data.N<pb->data.N)   //如果B中当前元素的次数高于A中当前元素
        {                           //则将该元素添加到pa之前
            auto temp=pb->next;     //记录pb在B中的后继
            pb->next=pa;
            preva->next=pb;
            preva=pb;           //preva始终指向pa的前一个元素
            pb=temp;            //在B中后移pb
        }
        else if(pa->data.N==pb->data.N)    //如果元素次数相等
        {
            pa->data.E+=pb->data.E;     //则系数相加存入A中
            if(fabs( pa->data.E)<1e-6)  //如果系数之和为0
            {
                La->Length-=2;     //将这一对系数互为相反数的项
                auto temp=pa;       //同时从A和B中删去,
                preva->next=pa->next;   //所以减2(联系前边La->Length+=Lb->Length;)。
                pa=pa->next;   //准备删去pa所指
                free(temp);
                temp=pb;        //准备删去pb所指
                pb=pb->next;
                free(temp);
                continue;   //下一轮比较
            }
            auto temp=pb;   //如果系数和不为零
            pb=pb->next;    //pa,pb都后移
            free(temp);
            preva=pa;
            pa=pa->next;
            La->Length--;   //相当于合并同类项,长度减1
        }
        else
        {
            preva=pa;   //如果pa次数高于pb
            pa=pa->next;    //pa后移,再与pb比较
        }
    }
    if(pb)      //如果pb非空,
    {    // 说明B中还有剩余项(次数一定比A最小项小)

        preva->next=pb; //那么将剩余项连接到A上

    }
    free(Lb);   //B用不着了
}
int main()
{
    unsigned int n;
    cin>>n;
    Node A;
    Init_List(A,n);
    cin>>n;
    Node B;
    Init_List(B,n);
    Add_List(A,B);
    Print_List(A);
    return 0;
}

易错:

输出最后没有空格;
系数全部保留一位小数;
系数为0的项不显示;
即使相加之后的元素个数为0,也要输出其个数(0);
注意两多项式中两个元素互为相反数的情况;

猜你喜欢

转载自blog.csdn.net/qq_37613112/article/details/87956215
今日推荐