如何在 C 中随机找到具有一些连续元素的子数组?
How can I find a subarray with some contiguous elements randomly in C?
我有一个包含 100 个元素的数组。数组元素是一组 1 和 0。例如:
Array[100] = {0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,1,....,1}
我需要找到所有零 windows(gaps) 并随机选择其中一个。根据 1 到 20 之间的均匀分布选择间隙的大小(需要)。
needed = op_dist_load ("uniform_int", 1, 20);
例如,如果我们假设数组[100]中的其余元素等于 1,如您所见,我有 8 个零 windows([=25= 的大小] =2).我需要找到他们。
find_gap_randomly
函数选择了2个连续的零元素(有2个零元素的子数组意味着我的程序中存在间隙)。对于在不使用随机库的情况下用 C 语言编写 find_gap_randomly(int needed)
函数的代码,您有什么建议,最好是用于 OPNET 模拟器?
static void find_gap_randomly(int needed)
{
//The macros “FIN” and “FOUT” are used in OPNET functions to enable the OPNET
//debugging kernel to print out function information.
FIN(find_rr_gap());
/* ... */
FOUT;
}
如果您仍在寻找 Array
中的 差距 ,(差距 定义为连续的数量至少 needed
长度的零元素),那么找到所有间隙的一种简单、直接的方法是移动 "sliding-window" of needed
向下排列数组,检查 window 中的所有值是否为零。如果它们都为零,则您找到了一个间隙,如果没有,则移动到 Array
中的下一个索引并重复。
这个概念虽然相当简单,但图片可能会有所帮助(或尝试图片)
+-------+
| | <= window to slide over array
| |
+---+---+---+---+---+---+---+---+...
| 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | <= array values
+---+---+---+---+---+---+---+---+...
0 1 2 3 4 5 6 7 8 <= array indexes
| |
+-------+
上面显示了 Array
的前九个元素,下面是每个元素的相应索引。由于您的 needed
是 2
,您有一个跨越 2-elements
的 window,您将从 Array
的开头移动到结尾,检查其中的值。这可以简单地通过两个嵌套循环来完成,外循环循环 while i = needed; i < num_elements; i++
,然后内循环从 j = i - needed; j < i; j++
开始迭代。
要捕获 Array
中的间隙所在的位置,您使用第二个数组(我称为 gaps
)包含与 Array
初始化时相同数量的元素全零。当您在 Array
中找到一个区域,其中有 needed
个连续元素时,您只需递增 gaps[j]++;
即可将 gaps[j]
处的值从 0
设置为 1
。 (取决于 j
的 范围 ,如果 j
超出范围,您可能需要增加 gaps[i-needed]++;
。
当您完成从头到尾移动滑动 window 后,gaps
将在间隙开始位于 Array
.
实现滑动的简单函数window可以这样写:
/** find_gaps locates each sequence of all zero within 'array' of
* at least 'needed' length, the corresponding index within 'gaps'
* is incremented to identify the start of each gap, returns the
* number of gaps of 'needed' length in 'array'.
*/
int find_gaps (int *gaps, int *arr, int nelem, int needed)
{
int ngaps = 0; /* count of gaps found */
/* add code to validate parameters here */
memset (gaps, 0, nelem * sizeof *gaps); /* zero gaps array */
for (int i = needed; i < nelem; i++) { /* loop needed to end */
for (int j = i - needed; j < i; j++) { /* loop previous needed */
if (arr[j] != 0) /* if non-zero value, get next in array */
goto next; /* lowly 'goto' works fine here */
}
gaps[i-needed]++; /* increment index in gaps */
ngaps++; /* increment no. of gaps found */
next:;
}
return ngaps; /* return no. of gaps found */
}
(注意: 内部循环可以替换为 memcmp
以检查一个值,将所有字节设置为零以定位间隙)
完成上面 find_gaps
的操作,以图表为指导,确保您准确理解正在发生的事情。如果没有,请告诉我。
将它放在一个简短的示例中,将 needed
作为程序的第一个参数(如果没有给出参数,则默认使用 2
),您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/** find_gaps locates each sequence of all zero within 'array' of
* at least 'needed' length, the corresponding index within 'gaps'
* is incremented to identify the start of each gap, returns the
* number of gaps of 'needed' length in 'array'.
*/
int find_gaps (int *gaps, int *arr, int nelem, int needed)
{
int ngaps = 0; /* count of gaps found */
/* add code to validate parameters here */
memset (gaps, 0, nelem * sizeof *gaps); /* zero gaps array */
for (int i = needed; i < nelem; i++) { /* loop needed to end */
for (int j = i - needed; j < i; j++) { /* loop previous needed */
if (arr[j] != 0) /* if non-zero value, get next in array */
goto next; /* lowly 'goto' works fine here */
}
gaps[i-needed]++; /* increment index in gaps */
ngaps++; /* increment no. of gaps found */
next:;
}
return ngaps; /* return no. of gaps found */
}
int main (int argc, char **argv) {
int array[] = { 0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,0,0,
0,1,1,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1 },
nelem = sizeof array / sizeof *array, /* number of elements */
gaps[nelem], /* a VLA is fine here C99+, otherwise allocate */
ngaps = 0, /* no. of gaps found */
needed = argc > 1 ? strtol (argv[1], NULL, 0) : 2; /* (default: 2) */
if (errno) { /* validate strtol conversion succeeded */
perror ("strtol-argv[1]");
return 1;
}
/* find the number of gaps, storing beginning index in 'gaps' array */
ngaps = find_gaps (gaps, array, nelem, needed);
printf ("gaps found: %d\n", ngaps); /* output number of gaps */
for (int i = 0; ngaps && i < nelem; i++) /* output index of gaps */
if (gaps[i])
printf (" gap at array[%2d]\n", i);
return 0;
}
(注意: 你应该添加 needed
小于 nelem
的检查,但是那个和任何额外的验证都留给你作为练习)
例子Use/Output
$ ./bin/findgaps
gaps found: 11
gap at array[ 0]
gap at array[ 9]
gap at array[10]
gap at array[11]
gap at array[12]
gap at array[18]
gap at array[19]
gap at array[25]
gap at array[26]
gap at array[32]
gap at array[37]
检查至少 3 个零的间隙:
$ ./bin/findgaps 3
gaps found: 5
gap at array[ 9]
gap at array[10]
gap at array[11]
gap at array[18]
gap at array[25]
有几种方法可以解决这个问题,但是滑动-window 可能是最直接的一种,滑动-window 在 C 语言中还有许多其他应用,因此非常值得添加到您的工具箱中。如果您还有其他问题,请告诉我。
我有一个包含 100 个元素的数组。数组元素是一组 1 和 0。例如:
Array[100] = {0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,1,1,....,1}
我需要找到所有零 windows(gaps) 并随机选择其中一个。根据 1 到 20 之间的均匀分布选择间隙的大小(需要)。
needed = op_dist_load ("uniform_int", 1, 20);
例如,如果我们假设数组[100]中的其余元素等于 1,如您所见,我有 8 个零 windows([=25= 的大小] =2).我需要找到他们。
find_gap_randomly
函数选择了2个连续的零元素(有2个零元素的子数组意味着我的程序中存在间隙)。对于在不使用随机库的情况下用 C 语言编写 find_gap_randomly(int needed)
函数的代码,您有什么建议,最好是用于 OPNET 模拟器?
static void find_gap_randomly(int needed)
{
//The macros “FIN” and “FOUT” are used in OPNET functions to enable the OPNET
//debugging kernel to print out function information.
FIN(find_rr_gap());
/* ... */
FOUT;
}
如果您仍在寻找 Array
中的 差距 ,(差距 定义为连续的数量至少 needed
长度的零元素),那么找到所有间隙的一种简单、直接的方法是移动 "sliding-window" of needed
向下排列数组,检查 window 中的所有值是否为零。如果它们都为零,则您找到了一个间隙,如果没有,则移动到 Array
中的下一个索引并重复。
这个概念虽然相当简单,但图片可能会有所帮助(或尝试图片)
+-------+
| | <= window to slide over array
| |
+---+---+---+---+---+---+---+---+...
| 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | <= array values
+---+---+---+---+---+---+---+---+...
0 1 2 3 4 5 6 7 8 <= array indexes
| |
+-------+
上面显示了 Array
的前九个元素,下面是每个元素的相应索引。由于您的 needed
是 2
,您有一个跨越 2-elements
的 window,您将从 Array
的开头移动到结尾,检查其中的值。这可以简单地通过两个嵌套循环来完成,外循环循环 while i = needed; i < num_elements; i++
,然后内循环从 j = i - needed; j < i; j++
开始迭代。
要捕获 Array
中的间隙所在的位置,您使用第二个数组(我称为 gaps
)包含与 Array
初始化时相同数量的元素全零。当您在 Array
中找到一个区域,其中有 needed
个连续元素时,您只需递增 gaps[j]++;
即可将 gaps[j]
处的值从 0
设置为 1
。 (取决于 j
的 范围 ,如果 j
超出范围,您可能需要增加 gaps[i-needed]++;
。
当您完成从头到尾移动滑动 window 后,gaps
将在间隙开始位于 Array
.
实现滑动的简单函数window可以这样写:
/** find_gaps locates each sequence of all zero within 'array' of
* at least 'needed' length, the corresponding index within 'gaps'
* is incremented to identify the start of each gap, returns the
* number of gaps of 'needed' length in 'array'.
*/
int find_gaps (int *gaps, int *arr, int nelem, int needed)
{
int ngaps = 0; /* count of gaps found */
/* add code to validate parameters here */
memset (gaps, 0, nelem * sizeof *gaps); /* zero gaps array */
for (int i = needed; i < nelem; i++) { /* loop needed to end */
for (int j = i - needed; j < i; j++) { /* loop previous needed */
if (arr[j] != 0) /* if non-zero value, get next in array */
goto next; /* lowly 'goto' works fine here */
}
gaps[i-needed]++; /* increment index in gaps */
ngaps++; /* increment no. of gaps found */
next:;
}
return ngaps; /* return no. of gaps found */
}
(注意: 内部循环可以替换为 memcmp
以检查一个值,将所有字节设置为零以定位间隙)
完成上面 find_gaps
的操作,以图表为指导,确保您准确理解正在发生的事情。如果没有,请告诉我。
将它放在一个简短的示例中,将 needed
作为程序的第一个参数(如果没有给出参数,则默认使用 2
),您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/** find_gaps locates each sequence of all zero within 'array' of
* at least 'needed' length, the corresponding index within 'gaps'
* is incremented to identify the start of each gap, returns the
* number of gaps of 'needed' length in 'array'.
*/
int find_gaps (int *gaps, int *arr, int nelem, int needed)
{
int ngaps = 0; /* count of gaps found */
/* add code to validate parameters here */
memset (gaps, 0, nelem * sizeof *gaps); /* zero gaps array */
for (int i = needed; i < nelem; i++) { /* loop needed to end */
for (int j = i - needed; j < i; j++) { /* loop previous needed */
if (arr[j] != 0) /* if non-zero value, get next in array */
goto next; /* lowly 'goto' works fine here */
}
gaps[i-needed]++; /* increment index in gaps */
ngaps++; /* increment no. of gaps found */
next:;
}
return ngaps; /* return no. of gaps found */
}
int main (int argc, char **argv) {
int array[] = { 0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,0,0,
0,1,1,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,0,1 },
nelem = sizeof array / sizeof *array, /* number of elements */
gaps[nelem], /* a VLA is fine here C99+, otherwise allocate */
ngaps = 0, /* no. of gaps found */
needed = argc > 1 ? strtol (argv[1], NULL, 0) : 2; /* (default: 2) */
if (errno) { /* validate strtol conversion succeeded */
perror ("strtol-argv[1]");
return 1;
}
/* find the number of gaps, storing beginning index in 'gaps' array */
ngaps = find_gaps (gaps, array, nelem, needed);
printf ("gaps found: %d\n", ngaps); /* output number of gaps */
for (int i = 0; ngaps && i < nelem; i++) /* output index of gaps */
if (gaps[i])
printf (" gap at array[%2d]\n", i);
return 0;
}
(注意: 你应该添加 needed
小于 nelem
的检查,但是那个和任何额外的验证都留给你作为练习)
例子Use/Output
$ ./bin/findgaps
gaps found: 11
gap at array[ 0]
gap at array[ 9]
gap at array[10]
gap at array[11]
gap at array[12]
gap at array[18]
gap at array[19]
gap at array[25]
gap at array[26]
gap at array[32]
gap at array[37]
检查至少 3 个零的间隙:
$ ./bin/findgaps 3
gaps found: 5
gap at array[ 9]
gap at array[10]
gap at array[11]
gap at array[18]
gap at array[25]
有几种方法可以解决这个问题,但是滑动-window 可能是最直接的一种,滑动-window 在 C 语言中还有许多其他应用,因此非常值得添加到您的工具箱中。如果您还有其他问题,请告诉我。