C 循环遍历和比较数组的子集
我有两个阵列:C 循环遍历和比较数组的子集,c,algorithm,C,Algorithm,我有两个阵列: int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3}; int value[] = {1, 0, 3, 5, 0, 2, 1, 6}; 从第二个数组中,我需要返回group\u id索引中的最大值(不包括当前索引位置),结果(在新数组中)为: {0, 1, 5, 3, 5, 6, 6, 2} 阵列要长得多(约1000万),因此正在寻找一种高效的解决方案 澄清: value的前两个元素属于group\u id=1,第一个元素将返回0作为最高
int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3};
int value[] = {1, 0, 3, 5, 0, 2, 1, 6};
从第二个数组中,我需要返回group\u id
索引中的最大值(不包括当前索引位置),结果(在新数组中)为:
{0, 1, 5, 3, 5, 6, 6, 2}
阵列要长得多(约1000万),因此正在寻找一种高效的解决方案
澄清:
value
的前两个元素属于group\u id
=1,第一个元素将返回0作为最高值,因为它无法返回自身。第二个元素将返回1,因为它是group\u id
1中的最大值
第三、第四和第五个元素(3、5、0)属于group\u id
2,第一个元素返回5,第二个元素返回3(因为它不能返回自己的索引,第三个元素返回5)
尚不清楚组_id中具有相同编号的所有元素是否相邻(但这对效率至关重要) 很好,你可以假设它们都是相邻的 如果group_id中只有一个条目具有给定的值,则不清楚应该发生什么-没有可供选择的条目可供使用,因此应该发生什么(或者如果输入无效,代码应该放弃)
假设无效。以下代码将执行此操作。它的效率是O(所有n_ilog(n_i)的总和),其中n_i是每个子集i的大小,除非我们使用MPI或OpenMP(在这种情况下,它最多是O(mlog(m)),其中m是最大子集的大小)
#包括
#包括
#包括
整数比较(常数无效*e1,常数无效*e2)
{
int f=*((int*)e1);
int s=*((int*)e2);
返回(f>s);
}
int main(int argc,char*argv[])
{
int group_id[]={1,1,2,2,2,3,3,3};
int值[]={1,0,3,5,0,2,1,6};
int i,j,k,count,*tmp;
对于(i=0;i,下面的代码就可以了。它的效率是O(所有n_ilog(n_i)的总和),其中n_i是每个子集i的大小,除非我们使用MPI或OpenMP(在这种情况下,它最多是O(mlog(m)),其中m是最大子集的大小)
#包括
#包括
#包括
整数比较(常数无效*e1,常数无效*e2)
{
int f=*((int*)e1);
int s=*((int*)e2);
返回(f>s);
}
int main(int argc,char*argv[])
{
int group_id[]={1,1,2,2,2,3,3,3};
int值[]={1,0,3,5,0,2,1,6};
int i,j,k,count,*tmp;
对于(i=0;i问题可以在O(N)时间内解决;它不需要O(N•log N)和排序。此代码显示了如何:
/* SO 5723-6683 */
#include <assert.h>
#include <stdio.h>
static void dump_array(const char *tag, int size, int *data);
static void test_array(const char *tag, int size, int *groups, int *values);
int main(void)
{
int groups1[] = { 1, 1, 2, 2, 2, 3, 3, 3 };
int values1[] = { 1, 0, 3, 5, 0, 2, 1, 6 };
int groups2[] = { 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5 };
int values2[] = { 1, 1, 3, 5, 0, 2, 1, 6, 6, 3, 5, 5, 5, 3, 2, 3, 7, 3 };
enum { NUM_VALUES1 = sizeof(values1) / sizeof(values1[0]) };
enum { NUM_VALUES2 = sizeof(values2) / sizeof(values2[0]) };
test_array("Test 1", NUM_VALUES1, groups1, values1);
test_array("Test 2", NUM_VALUES2, groups2, values2);
return 0;
}
static void test_array(const char *tag, int size, int *groups, int *values)
{
printf("%s (%d):\n", tag, size);
dump_array("values", size, values);
dump_array("groups", size, groups);
int output[size];
int grp_size;
for (int lo = 0; lo < size - 1; lo += grp_size)
{
assert(groups[lo+0] == groups[lo+1]);
grp_size = 2;
int max_1 = (values[lo+0] < values[lo+1]) ? values[lo+1] : values[lo+0];
int max_2 = (values[lo+0] < values[lo+1]) ? values[lo+0] : values[lo+1];
for (int hi = lo + 2; hi < size && groups[hi] == groups[lo]; hi++)
{
grp_size++;
if (values[hi] >= max_1)
{
max_2 = max_1;
max_1 = values[hi];
}
else if (values[hi] >= max_2)
max_2 = values[hi];
}
for (int i = lo; i < lo + grp_size; i++)
output[i] = (values[i] == max_1) ? max_2 : max_1;
}
dump_array("output", size, output);
}
static void dump_array(const char *tag, int size, int *data)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", data[i]);
putchar('\n');
}
这个问题可以在O(N)时间内解决;它不需要O(N•log N)和排序。此代码显示了如何:
/* SO 5723-6683 */
#include <assert.h>
#include <stdio.h>
static void dump_array(const char *tag, int size, int *data);
static void test_array(const char *tag, int size, int *groups, int *values);
int main(void)
{
int groups1[] = { 1, 1, 2, 2, 2, 3, 3, 3 };
int values1[] = { 1, 0, 3, 5, 0, 2, 1, 6 };
int groups2[] = { 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5 };
int values2[] = { 1, 1, 3, 5, 0, 2, 1, 6, 6, 3, 5, 5, 5, 3, 2, 3, 7, 3 };
enum { NUM_VALUES1 = sizeof(values1) / sizeof(values1[0]) };
enum { NUM_VALUES2 = sizeof(values2) / sizeof(values2[0]) };
test_array("Test 1", NUM_VALUES1, groups1, values1);
test_array("Test 2", NUM_VALUES2, groups2, values2);
return 0;
}
static void test_array(const char *tag, int size, int *groups, int *values)
{
printf("%s (%d):\n", tag, size);
dump_array("values", size, values);
dump_array("groups", size, groups);
int output[size];
int grp_size;
for (int lo = 0; lo < size - 1; lo += grp_size)
{
assert(groups[lo+0] == groups[lo+1]);
grp_size = 2;
int max_1 = (values[lo+0] < values[lo+1]) ? values[lo+1] : values[lo+0];
int max_2 = (values[lo+0] < values[lo+1]) ? values[lo+0] : values[lo+1];
for (int hi = lo + 2; hi < size && groups[hi] == groups[lo]; hi++)
{
grp_size++;
if (values[hi] >= max_1)
{
max_2 = max_1;
max_1 = values[hi];
}
else if (values[hi] >= max_2)
max_2 = values[hi];
}
for (int i = lo; i < lo + grp_size; i++)
output[i] = (values[i] == max_1) ? max_2 : max_1;
}
dump_array("output", size, output);
}
static void dump_array(const char *tag, int size, int *data)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", data[i]);
putchar('\n');
}
我看过输入、输出和描述,我不知道如何从输入中生成输出,也不知道“不包括当前指数位置”的意义注释。也许你需要更清楚地解释你想做什么。是否巧合的是组id
数组是按顺序排序的?@JonathanLeffler,这里我认为我是唯一一个。不管怎样,这似乎更像是一个算法问题,而不是关于C的问题。也许……从输出数组(O)中的索引0开始。您扫描组数组以查找组[0](也称为1)中的值,并在值数组中找到具有相同组号但不是索引0中的最大项。组[0]值为1,因此其他项(组[1])匹配,值[1]为0。没有其他候选项,因此O[0]=0。对于O[1],组[1]值为1,因此条目值为0[0]是输出-O[1]==1。对于O[2],组更改为2,其他条目为5和0,因此O[2]为5;对于O[3],其他元素为3和0,因此O[3]为3;然后O[4]再次为5,以此类推。不清楚组id
中具有相同编号的所有元素是否相邻(但这对效率至关重要)。如果组\u id
中只有一个条目具有给定值,则不清楚应该发生什么情况-没有可供选择的条目可供使用,因此应该发生什么情况(或者如果输入无效,代码应该放弃)。您可能只需要跟踪给定组id值中的最大值和第二最大值-输出将是这两个值中的一个或另一个。我查看了输入、输出和描述,不知道如何从输入生成输出,也不知道“不包括当前指数头寸“评论。也许你需要更清楚地解释你想做什么。是否巧合的是,group\u id
数组是按顺序排列的?@JonathanLeffler,这里我认为我是唯一一个。不管怎样,这似乎更像是一个算法问题,而不是关于C的问题。也许……从输出数组(O)中的索引0开始。”。您扫描组数组以查找组[0](也称为1)中的值,并在值数组中找到具有相同组号但不是索引0中的最大项。组[0]值为1,因此其他项(组[1])匹配,值[1]为0。没有其他候选项,因此O[0]=0。对于O[1],组[1]值为1,因此条目值为0[0]是输出-O[1]==1。对于O[2],组更改为2,其他条目为5和0,因此O[2]为5;对于O[3],其他元素为3和0,因此O[3]为3;然后O[4]再次为5,以此类推。不清楚组id
中具有相同编号的所有元素是否相邻(但这对效率至关重要)。如果组\u id
中只有一个条目具有给定值,则不清楚应该发生什么情况-没有可供选择的条目可供使用,因此应该发生什么情况(或者如果输入无效,代码应该放弃)。您可能只需要跟踪给定组id值的值中的最大值和第二个最大值-输出将是这两个值中的一个或另一个。您还可以将数据成对排列(组id,值)并对它们进行排序,这可能比上述方法更有效,但
Test 1 (8):
values (8): 1 0 3 5 0 2 1 6
groups (8): 1 1 2 2 2 3 3 3
output (8): 0 1 5 3 5 6 6 2
Test 2 (18):
values (18): 1 1 3 5 0 2 1 6 6 3 5 5 5 3 2 3 7 3
groups (18): 1 1 2 2 2 3 3 3 3 3 4 4 4 5 5 5 5 5
output (18): 1 1 5 3 5 6 6 6 6 6 5 5 5 7 7 7 3 7