2

これは、2 つの多項式の GCD を見つけるプログラムを実装しようとする私の試みです。分割方法に問題があることに気づきました。結果の多項式の次数をデクリメントする while ループは、division()場合によっては「無限大」に入りますが、正確に理解できません。

ここで何がうまくいかないかについての手がかりはありますか?

#include<iostream>
#include<stdlib.h>



using namespace std;

//polynomial------------------------------
struct polynomial {
    float *coeff;
    int degree;
};

/*function declaration */
int get_data(polynomial *P); 
int display(polynomial *P);
int division(polynomial *P, polynomial *Q, polynomial *H, polynomial *R);
int polcpy(polynomial *p, polynomial *q);
void GCDPol(polynomial *P,polynomial *Q, polynomial *R);

//GCD of two polynomials------------------
void GCDpol(polynomial *P,polynomial *Q, polynomial *R) {
    polynomial *res, *v;
    res = (polynomial *) calloc(1,sizeof(polynomial));  
    v = (polynomial *) calloc(1,sizeof(polynomial));  
    while(1) {
        division(P, Q, v, R);
        if(R->degree==0 && R->coeff[0]==0)
            break;
        else
            polcpy(P,Q);
            polcpy(Q,R);
    }
    polcpy(R,Q);
    free(res);
    free(v);
}

//pol copy--------------------------------
int polcpy(polynomial *p, polynomial *q) {
    p->degree=q->degree;
    p->coeff = new float[p->degree + 1];
    for (int i=0; i<=p->degree; i++) 
        p->coeff[i]=q->coeff[i];
    return 0;
}

//division--------------------------------
int division(polynomial *P, polynomial *Q, polynomial *H, polynomial *R) {
    float u;
    int x;
    polynomial *nh, *nr;
    nh = (polynomial *) calloc(1,sizeof(polynomial));
    nr = (polynomial *) calloc(1,sizeof(polynomial));

    /*Euclidian Long Division*/
    polcpy(nr, P);  
    nh->degree = P->degree - Q->degree;
    nh->coeff = new float[nh->degree + 1];
    for (int i=nh->degree; i>=0; i--)  {
        nh->coeff[i] = nr->coeff[nr->degree] / Q->coeff[Q->degree];
        for (int j=i; j <= nr->degree; j++) {
            u = nh->coeff[i] * Q->coeff[j-i];
            nr->coeff[j] = nr->coeff[j] - u;
        }
        if (nr->degree > 0)  
            nr->degree--;
    }

    /*Quotient*/
    polcpy(H, nh);  
    /*Remainder*/   
    polcpy(R, nr);
    while(R->coeff[R->degree] == 0) {
        R->degree--;
    }   
    free(nh); 
    free(nr);
    return 0;
}

//display-------------------------------
int display(polynomial *P) {
    int i, j;
    for (i = P->degree; i >= 0; i--) {
        cout << P->coeff[i] << "x^" << i;
        if ((i - 1) != -1)
            cout << "+";
    }
    cout << "\n";
    return 0;
}

//get_data------------------------------
int get_data(polynomial *P) {
    cout << "Enter Degree Of Polynomial:";
    cin >> P->degree;
    P->coeff = new float[P->degree + 1];
    for (int i = P->degree; i >= 0; i--) {
        cout << "Enter coefficient of x^" << i << ":";
        cin >> P->coeff[i];
    }
    return 0;
}


int main() {
    polynomial *P, *Q, *R, *H;
    P = (polynomial *) calloc(1,sizeof(polynomial));
    Q = (polynomial *) calloc(1,sizeof(polynomial));
    R = (polynomial *) calloc(1,sizeof(polynomial));
    H = (polynomial *) calloc(1,sizeof(polynomial));
    cout<<"GDC\n";
    get_data(P);
    get_data(Q);
    cout << "Polynomial1:";
    display(P);
    cout << "Polynomial2:";
    display(Q);
    GCDpol(P,Q,R);
    display(R);
    free(R);
    free(P);
    free(Q);
    free(H);
    return 0;
}
4

3 に答える 3

1

ラインの可能性が高いと思われる

if(R->degree==0 && R->coeff[0]==0)
        break;

壊れたものです。あなたの係数は浮動小数点数です。コンピューターは (残念ながら) 有限であるため、float の計算には小さなエラーが発生します。係数が正確に 0 の場合にのみ、コードは while ループを終了します。一部の入力では、均等に分割する必要がありますがR->coeff[0] = 0.0000000001、正確に 0 ではない他の非常に小さな値を取得する可能性があります。

絶対値が非常に小さな許容範囲 (10^-10 や 10^-12 など) 内にあるかどうかを確認してください。実際に正確な値が必要な場合は、正確な精度の浮動小数点数を調べる必要があります。ワームの。

(コードをより詳しく見ると、他の場所でも正確な等値チェックを行っています。これらはすべて、絶対値が非常に小さいことを確認するように変更する必要があります。)

于 2015-04-10T04:19:41.663 に答える
1
while(R->coeff[R->degree] == 0) {
    R->degree--;
}

Rがゼロ多項式の場合、これはひどく間違っています。

于 2015-04-09T22:07:02.380 に答える
1

この C++ ライブラリは多項式除算を実装しています: PolynomialDivHang_test_no_hang

于 2018-12-20T08:54:31.100 に答える