C试图修复无限循环

时间:2019-02-27 13:59:46

标签: c algorithm random

我有一个获取索引值的函数,将其放入数组中。然后使用rand + srand( key )生成一个新的新随机索引。并且它会检查新生成的索引是否已经在数组中,它将继续生成新索引并检查直到生成唯一值。

问题在于它对于较小的可以很好地工作,但是在较长的键处会陷入无限循环,并且永远找不到唯一的值。这是我的代码:

int getNewIndex(PPM *im, int index, int *visitedPixels, int *visitedPixelsIndex) {

    int i = 0;
    if(*visitedPixelsIndex == im->height) {
        perror("Cannot encode anymore: pixels limit reached");
        exit(1);
    }

    visitedPixels[*visitedPixelsIndex] = index;
    (*visitedPixelsIndex)++;
    // If index is already in the list, generate a new number and check again.
    while (i < *visitedPixelsIndex) {
        if(index == visitedPixels[i]) {
            index = rand() % im->height;
            i = 0;
        } else {
            i++;
        }
    }

    return index;
}

编辑:im->height,即图像高度,平均约为400-600。

1 个答案:

答案 0 :(得分:1)

据我所知,当您将最后一个空闲索引插入数组时,代码将生成无限循环。

假设:

1)im->height为500,因此有效索引在[0 .. 499]范围内

2)您已经插入了499个值,即*visitedPixelsIndex是499

因此,在调用该函数时,条件*visitedPixelsIndex == im->height将为false,因此您不退出而是继续,然后在数组中插入值500。

然后您执行(*visitedPixelsIndex)++;,以使*visitedPixelsIndex变为500。

之后,您进入while循环,尝试查找新的未使用的index。但是-因为您已经使用了所有500个有效索引值,所以永远找不到未使用的索引。

换句话说-无限循环

也许您应该这样做:

(*visitedPixelsIndex)++;
if(*visitedPixelsIndex == im->height) {
    perror("Cannot encode anymore: pixels limit reached");
    exit(1);
}

我还认为您应该在index循环之前之前生成一个新的while

但是,总的来说,我认为如果将当前函数分为两个函数,您的代码会更清晰。喜欢

int isPresent(int index, int *visitedPixels, int N) 
{
    for(int i = 0; i<N; ++i)
    {
        if (index == visitedPixels[i]) return 1;
    }
    return 0;
}

int getNewIndex(PPM *im, int index, int *visitedPixels, int *visitedPixelsIndex) 
{
    visitedPixels[*visitedPixelsIndex] = index;

    (*visitedPixelsIndex)++;

    if (*visitedPixelsIndex == im->height) {
        perror("Cannot encode anymore: pixels limit reached");
        exit(1);
    }

    do
    {
        index = rand() % im->height;
    } while(isPresent(index, visitedPixels, *visitedPixelsIndex));

    return index;
}