C 使用递归的成对差分

C 使用递归的成对差分,c,arrays,recursion,segmentation-fault,C,Arrays,Recursion,Segmentation Fault,我被要求将这个伪代码翻译成C程序: rep := 0 while A not empty: B := [] for x in A, y in A: if x != y: append absolute_value(x - y) to B A := B rep := rep + 1 最后,我得出以下结论: int iterateIt(int a_count, int* a) { unsigned long long i, j, k;

我被要求将这个伪代码翻译成C程序:

rep := 0
while A not empty:
    B := []
    for x in A, y in A:
        if x != y: append absolute_value(x - y) to B
    A := B
    rep := rep + 1
最后,我得出以下结论:

int iterateIt(int a_count, int* a) {
    unsigned long long i, j, k;
    unsigned long long count = a_count;

    for( i = 1 ; i < a_count ; i++ )
        count *= count-1;

    int *b = (int *) malloc(count * sizeof(int));
    count = 0;
    k = 0;
    for( i = 0 ; i < a_count ; i++ ){
        for( j = i ; j < a_count ; j++ ){
            if(a[i] != a[j]){
                b[k] = abs(a[i] - a[j]);
                k++;
            }
        }
    }

    if( k > 0){
        return 1 + iterateIt(k, b);
    }
    free(b);
    return 1;
}
intiterateit(inta_计数,int*a){
无符号长i,j,k;
无符号长计数=a_计数;
对于(i=1;i0){
返回1+iterateIt(k,b);
}
免费(b);
返回1;
}
我使用递归返回算法的迭代次数。实际上,我取A的任意两个不同对象之间的差,把绝对值放在B中,我在B上重复。 对于简单的输入,我得到了正确的结果,但我不明白为什么对于以下输入:
16
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
4
13529483 50000
(第一个数字是A的元素数)

我得到一个分段错误


谢谢你的帮助

我想你的
计数是错的。您的第二次迭代已经非常庞大

#include <stdio.h>
#include <stdlib.h>

size_t total_allocated = 0;

int iterateIt(int a_count, int* a) {
    unsigned long long i, j, k;
    unsigned long long count = a_count;

    for( i = 1 ; i < a_count ; i++ )
        count *= count-1;

    size_t size = count * sizeof(int);
    printf("Allocating %llu ints: %llu bytes\n", count, (unsigned long long)size);
    total_allocated += size;
    printf("Total allocated: %llu bytes\n", (unsigned long long)total_allocated);
    int *b = (int *) malloc(count * sizeof(int));
    count = 0;
    k = 0;
    for( i = 0 ; i < a_count ; i++ ){
        for( j = i ; j < a_count ; j++ ){
            if(a[i] != a[j]){
                b[k] = abs(a[i] - a[j]);
                k++;
            }
        }
    }

    if( k > 0){
        return 1 + iterateIt(k, b);
    }
    free(b);
    return 1;
}

int main (void)
{
    iterateIt(4, (int[4]){1,352,9483,50000});
    return 0;
}

我认为你的计数是错误的。您的第二次迭代已经非常庞大

#include <stdio.h>
#include <stdlib.h>

size_t total_allocated = 0;

int iterateIt(int a_count, int* a) {
    unsigned long long i, j, k;
    unsigned long long count = a_count;

    for( i = 1 ; i < a_count ; i++ )
        count *= count-1;

    size_t size = count * sizeof(int);
    printf("Allocating %llu ints: %llu bytes\n", count, (unsigned long long)size);
    total_allocated += size;
    printf("Total allocated: %llu bytes\n", (unsigned long long)total_allocated);
    int *b = (int *) malloc(count * sizeof(int));
    count = 0;
    k = 0;
    for( i = 0 ; i < a_count ; i++ ){
        for( j = i ; j < a_count ; j++ ){
            if(a[i] != a[j]){
                b[k] = abs(a[i] - a[j]);
                k++;
            }
        }
    }

    if( k > 0){
        return 1 + iterateIt(k, b);
    }
    free(b);
    return 1;
}

int main (void)
{
    iterateIt(4, (int[4]){1,352,9483,50000});
    return 0;
}

首先考虑这一行:

return 1 + iterateIt(k, b);
b
数组在此
return
上永远不会被释放,但如果
k
为零,则会释放。让我们重写这段代码来清理一下:

#include <stdio.h>
#include <stdlib.h>

unsigned iterateIt(size_t a_count, int *a) {

    unsigned rep = 1;

    int *b = calloc(a_count * a_count, sizeof(int));

    size_t k = 0;

    for (size_t i = 0; i < a_count; i++) {
        for (size_t j = i + 1; j < a_count; j++) {
            if (a[i] != a[j]) {
                b[k++] = abs(a[i] - a[j]);
            }
        }
    }

    if (k > 0) {
        rep += iterateIt(k, b);
    }

    free(b);

    return rep;
}

int main() {

    int x[] = {1, 324, 54};

    printf("%u\n", iterateIt(sizeof(x) / sizeof(int), x));

    return 0;
}

首先考虑这一行:

return 1 + iterateIt(k, b);
b
数组在此
return
上永远不会被释放,但如果
k
为零,则会释放。让我们重写这段代码来清理一下:

#include <stdio.h>
#include <stdlib.h>

unsigned iterateIt(size_t a_count, int *a) {

    unsigned rep = 1;

    int *b = calloc(a_count * a_count, sizeof(int));

    size_t k = 0;

    for (size_t i = 0; i < a_count; i++) {
        for (size_t j = i + 1; j < a_count; j++) {
            if (a[i] != a[j]) {
                b[k++] = abs(a[i] - a[j]);
            }
        }
    }

    if (k > 0) {
        rep += iterateIt(k, b);
    }

    free(b);

    return rep;
}

int main() {

    int x[] = {1, 324, 54};

    printf("%u\n", iterateIt(sizeof(x) / sizeof(int), x));

    return 0;
}

为什么要把
count*=count-1在循环中?它计算什么?您不需要测试
malloc()
的返回值。我猜想您正在计算
count
中的一个巨大的甚至是负的(因为溢出)值,
malloc()
因此失败,然后您试图通过生成的空指针进行写入。是否使用IDE?它有调试器吗?你知道怎么用吗?它是你最好的朋友,很容易让你解决这样的问题,而不必问我们为什么要把
count*=count-1在循环中?它计算什么?您不需要测试
malloc()
的返回值。我猜想您正在计算
count
中的一个巨大的甚至是负的(因为溢出)值,
malloc()
因此失败,然后您试图通过生成的空指针进行写入。是否使用IDE?它有调试器吗?你知道怎么用吗?它是你最好的朋友,很容易让你解决这样的问题,而不必问我们收敛性肯定存在:每一轮的最大值都会减小。但我不认为有理由采用递归方法。收敛性肯定存在:在每一轮中,最大值都会减小。不过,我不认为有理由使用递归方法。