0

嘿,我正在尝试将我编写的用于生成表示 Pascal 三角形的 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;
}

我收到错误消息:在三角形中设置位置的所有行的分配类型不兼容(即:triangle[position] = one;)。

有谁知道我可能做错了什么?

4

1 回答 1

3

mpz_t被定义为长度为 1 的数组struct __mpz_struct,这会阻止赋值。这样做是因为正常的 C 赋值是浅拷贝,并且各种 gmp 数字类型存储指向需要深度拷贝的“肢体”数组的指针。您需要使用mpz_setor mpz_init_set(甚至mpz_init_set_si)来分配 MP 整数,确保在使用前者之前初始化目标。

此外,您应该mpz_clear最多调用一次mpz_init(在这方面它们就像 malloc 和 free 一样,并且出于相同的原因)。通过在内部循环中调用mpz_init(new_nom)外部循环mpz_clear(new_num),您引入了一个错误,当您检查make_triangle. 但是,您甚至不需要new_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使用加法和减法而不是两个减法、乘法和除法来更新。看看你能不能弄清楚怎么做。

于 2010-04-29T21:55:27.490 回答