基于项索引将数组拆分为N组的算法(应该简单)

时间:2008-11-26 22:38:36

标签: algorithm arrays

我觉得它应该是非常简单明显的东西,但是在过去的半小时内就停留在这一点上并且不能继续前进。

我只需要根据元素索引将元素数组拆分为N组。

例如,我们有一个包含30个元素[e1,e2,... e30]的数组,必须分成N = 3组,如下所示:

group1: [e1, ..., e10]
group2: [e11, ..., e20]
group3: [e21, ..., e30]

我为N = 3想出了令人讨厌的混乱(伪语言,我在0和1上留下乘法只是为了澄清):

for(i=0;i<array_size;i++) {
   if(i>=0*(array_size/3) && i<1*(array_size/3) {
      print "group1";
   } else if(i>=1*(array_size/3) && i<2*(array_size/3) {
      print "group2";
   } else if(i>=2*(array_size/3) && i<3*(array_size/3)
      print "group3";
   }
}

但是什么是正确的一般解决方案?

感谢。

9 个答案:

答案 0 :(得分:8)

这样的事情怎么样?

for(i=0;i<array_size;i++) {
  print "group" + (Math.floor(i/(array_size/N)) + 1)
}

答案 1 :(得分:3)

这是一个小功能,可以做你想做的事情 - 它假设你知道你想要制作的团体数量:

function arrayToGroups(source, groups) {  

                     //This is the array of groups to return:
                     var grouped = [];

                     //work out the size of the group
                     groupSize = Math.ceil(source.length/groups);

                     //clone the source array so we can safely splice it
                     var queue = source;

                     for (var r=0;r<groups;r++) {
                       //Grab the next groupful from the queue, and append it to the array of groups
                       grouped.push(queue.splice(0, groupSize));            
                     }       
             return grouped;
}

你用它就像:

var herbs = ['basil', 'marjoram', 'aniseed', 'parsely', 'chives', 'sage', 'fennel', 'oregano', 'thyme', 'tarragon', 'rosemary'];

var herbGroups = arrayToGroups(herbs, 3);

返回:

herbGroups[0] = ['basil', 'marjoram', 'aniseed', 'parsely']
herbGroups[1] = ['chives', 'sage', 'fennel', 'oregano']
herbGroups[2] = ['thyme', 'tarragon', 'rosemary']

它不会进行任何健全性检查以确保传入数组和数字,但您可以轻松地添加它。您可以将它原型化为Javascript的对象类型,这将为您提供一个方便的'toGroups'方法在数组上。

答案 2 :(得分:2)

我在上面修改了Beejamin的功能,只是想分享它。

function arrayToGroups($source, $pergroup) {  
    $grouped = array();
    $groupCount = ceil(count($source)/$pergroup);
    $queue = $source;
    for ($r=0; $r<$groupCount; $r++) {
        array_push($grouped, array_splice($queue, 0, $pergroup));    
    }       
    return $grouped;
}

这会询问每组有多少项而不是总共有多少组。 PHP。

答案 3 :(得分:1)

 const int g = 3;                      // number of groups
 const int n = (array_size + g - 1)/g; // elements per group

 for (i=0,j=1; i<array_size; ++i) {
    if (i > j*n)
        ++j;
     printf("Group %d\n", j);
 }

答案 4 :(得分:1)

int group[3][10];
int groupIndex = 0;
int itemIndex = 0;
for(i = 0; i < array_size; i++)
{
    group[groupIndex][itemIndex] = big_array[i];
    itemIndex++;
    if (itemIndex == 10)
    {
        itemIndex = 0;
        groupIndex++;   
    }
}

答案 5 :(得分:1)

可能有无数种方法可以做到这一点。 我建议:对于每个组,创建一个基指针并计数。

struct group {foo * ptr; size_t count };
group * pgroups = new group [ngroups];
size_t objects_per_group = array_size / ngroups;
for (unsigned u = 0; u < ngroups; ++u ) {
   group & g =  pgroups[u];
   size_t index = u * objects_per_group;
   g.ptr = & array [index];
   g.count = min (objects_per_group, array_size - index);  // last group may have less!
}
...`
for (unsigned u = 0; u < ngroups; ++u) {
   // group "g" is an array at pgroups[g].ptr, dimension pgroups[g].count
   group & g =  pgroups[u];
   // enumerate the group:
   for (unsigned v = 0; v < g.count; ++v) {
      fprintf (stdout, "group %u, item %u, %s\n",
         (unsigned) u, (unsigned) v, (const char *) g.ptr[v]->somestring);
}  }

delete[] pgroups;

答案 6 :(得分:1)

使用矢量语言使这项任务变得简单,正确的工具和所有这些。我以为我会把它扔到那里让人们检查另一种方法。

K(APL后代)中的解释版本:

split:{[values;n]    / define function split with two parameters
  enum:!n            / ! does enumerate from 0 through n exclusive, : is assign
  floor:_(#values)%n / 33 for this sample, % is divide, _ floor, # count
  cut:floor*enum     / 0 33 66 for this sample data, * multiplies atom * vector
  :cut _ values      / cut the values at the given cutpoints, yielding #cut lists
  }

values:1+!30           / generate values 1 through 30
n:3                    / how many groups to split into
groups:split[values;n] / set the groups

产生预期的输出:

(1 2 3 4 5 6 7 8 9 10
 11 12 13 14 15 16 17 18 19 20
 21 22 23 24 25 26 27 28 29 30)

K中的简短版本:

split:{((_(#x)%y)*!y)_ x}
groups:split[1+!30;3]

产生相同的输出:

(1 2 3 4 5 6 7 8 9 10
 11 12 13 14 15 16 17 18 19 20
 21 22 23 24 25 26 27 28 29 30)

答案 7 :(得分:0)

我认为这个问题有点复杂;并且考虑到你只将组视为一维问题,你会得到一个非常奇怪的视图,看看实际上是什么组。

首先,问题是根据群组素数和您正在处理的群组合的维度。在数学;这表示n为n或n ^ n的幂,可以转换为!n(因子为n)。

如果我有5个阵列排列为(1,2,3,4,5),那么我想根据因子表达式将其表示为某些组或组的组合,然后组合变得更大

组1x1 = 1,2,3,4,5
组2x1 = 12,23,45,13,​​14,15,21,24,25,31,32,34,35,41,42,43,45,51,52,53,54 所以策略创建了一个分支系统分支(足够简单)
12,13,14,15
21,22,23,24
31,32,34,35
41,42,43,45
51,52,53,55
第1组+ 2x2x1 =(1,23,45),(2,13,45),(3,12,45),(4,12,35),(1,24,35),(1,25, 35),(1,32,45),(1,34,25),(1,35,24),......等

正如您所看到的,当您开始添加阶乘集时,组合变得不那么容易创建表达术语的数学参考。当你进入基本组时,它会变得最糟糕。 3或4长。

如果我理解你的问题:你想用通用术语表达一个允许你以编程方式创建分组策略的算法吗?

这是一个复杂的集合;并且在微积分中表现得最好;作为集合论。否则你所做的就是二维数组处理。

第一个Array表示分组策略; 第二个数组表示分组元素。

我不认为这是你被要求做的事情,因为数学中的术语“GROUP”对这个术语有一个非常具体的分配。你不应该使用术语组;而是把它表达为一组; set1,set2如果你正在做的那样。

Set1包含set2的元素;因此,这是用与表示集合和联合的相同数学来处理的。查找“Vin Diagrams”和“Union”;除非您表示集合的因子,否则请避免使用术语组。
http://en.wikipedia.org/wiki/Group_(mathematics)

我想你要表达的是已知集合或表格中的群体;这是在wikipedia.org示例D2上。

在这种情况下,这意味着你必须像rubik的立方体一样看待问题;它变得复杂
我在javascript中工作相同的问题;当我完成后,我可能会发布它;)。这很复杂。

答案 8 :(得分:0)

http://mathworld.wolfram.com/Permutation.html

添加到我说的话;这里是表示分组顺序排列的公式。