Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 循环遍历和比较数组的子集_C_Algorithm - Fatal编程技术网

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