我有一个获取索引值的函数,将其放入数组中。然后使用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。
答案 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;
}