0

パスカルの三角形を表す long の配列を生成するために書いた関数を、mpz_t の配列を返す関数に変換しようとしています。ただし、次のコードを使用します。

mpz_t* make_triangle(int rows, int* count) {
//compute triangle size using 1 + 2 + 3 + ... n = n(n + 1) / 2
*count = (rows * (rows + 1)) / 2;
mpz_t* triangle = malloc((*count) * sizeof(mpz_t));

//fill in first two rows
mpz_t one;
mpz_init(one);
mpz_set_si(one, 1);
triangle[0] = one; triangle[1] = one; triangle[2] = one;

int nums_to_fill = 1;
int position = 3;
int last_row_pos;
int r, i;
for(r = 3; r <= rows; r++) {
    //left most side
    triangle[position] = one;
    position++;

    //inner numbers
    mpz_t new_num;
    mpz_init(new_num);
    last_row_pos = ((r - 1) * (r - 2)) / 2;
    for(i = 0; i < nums_to_fill; i++) {
        mpz_add(new_num, triangle[last_row_pos + i], triangle[last_row_pos + i + 1]);
        triangle[position] = new_num;
        mpz_clear(new_num);
        position++;
    }
    nums_to_fill++;

    //right most side
    triangle[position] = one;
    position++;
}

return triangle;
}

三角形の位置が設定されているすべての行の割り当てに互換性のない型があります (つまり、三角形 [位置] = 1;) というエラーが表示されます。

私が間違っているかもしれないことを誰かが知っていますか?

4

1 に答える 1

3

mpz_tは長さ 1 の配列として定義されているため、struct __mpz_struct代入はできません。これが行われるのは、通常の C 代入が浅いコピーであり、さまざまな gmp 数値型がディープ コピーする必要がある「リム」の配列へのポインターを格納するためです。mpz_setまたはmpz_init_set(または) を使用して MP ​​整数を割り当てる必要がありmpz_init_set_si、前者を使用する前に必ず宛先を初期化してください。

また、呼び出しmpz_clearは多くても 1 回に 1 回にする必要がありmpz_initます (この点では malloc と free に似ており、同じ理由で)。mpz_init(new_nom)内側のループで外側のループを呼び出すとmpz_clear(new_num)、バグが発生します。これは、 の結果を調べると明らかになりますmake_trianglenew_numただし、 ;も必要ありません。の次の要素を初期化し、triangleそれを の宛先として使用しますmpz_add

    mpz_init(triangle[position]);
    mpz_add(triangle[position++], triangle[last_row_pos + i], triangle[last_row_pos + i + 1]);

last_row_pos小規模な数値最適化:乗算と除算の 2 つの減算ではなく、加算と減算を使用して更新できます。方法を理解できるかどうかを確認してください。

于 2010-04-29T21:55:27.490 に答える