2008-11-26 59 views
3

我覺得它應該是非常簡單明顯的東西,但是在最後半個小時內就停留在這一點上,無法繼續前進。根據項目索引將數組拆分爲N組的算法

我需要的是根據元素索引將一組元素分成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"; 
    } 
} 

但什麼是正確的通用解決方案?

謝謝。

+0

這個問題最重要的一個教訓是,邊界條件,短的(人爲的)期限和缺乏單元測試是一個致命的組合。 – 2008-11-27 02:23:47

+1

你到底想做什麼:分成3個小陣列,或打印「groupI」30次? – blabla999 2009-01-13 20:35:02

回答

8

什麼這樣的事情?

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

謝謝,最短的一個,沒有額外的變量。 – serg 2008-11-26 22:54:37

+0

設array_size = 8且N = 3。由於整數數學給出8/3 = 2,所以「3」組爲{0,1},{2,3},{3,4},{6,7} 。 – 2008-11-27 02:19:48

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); 
} 
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++; 
    } 
}
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; 
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) 
0

我覺得問題有點複雜;並且考慮到你只將組看作一維問題,你會對組的實際情況產生非常奇怪的看法。

首先,問題是根據組素數的數量以及您正在處理的組合。數學;這被表示爲能夠被翻譯成n(n的因子)的n或n^n的冪。

如果我已經5組排列爲(1,2,3,4,5),那麼我想它表示爲某些組或根據階乘表達式組combonations則combonations得到更大

組的1x1 = 1,2,3,4,5
組2×1 = 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
(1,12,45),(2,13,45),(3,12,45),(4),(2,13,45),(3,12,45),(4,14,15,16,17,18,19,20,21,22,24,25,25,27,27,27,27,28,29) ,12,35),(1,24,35),(1,25,35),(1,32,45),(1,34,25),(1,35,24),...等

當你開始添加因子,你可以看到設置comboniations變得不那麼容易創建的數學參考表達的條款。當你進入長度大於3或4的基座時,情況會變得更糟。

如果我理解你的問題:你想在一個通用術語表達algorythm它允許您以編程方式創建分組策略?

這是一個複雜集;在微積分中代表最好;作爲集合論。否則,你所做的只是一個二維數組處理。

第一陣列表達分組策略; 第二個數組表示分組元素。

我不認爲這是你被要求做什麼,因爲在數學術語「基」的術語一個非常具體的分配。你不應該使用術語組;而是將其表達爲一組; set1,set2,如果這是你在做什麼。

SET1包含SET2的元素;因此,這與數據處理的集合和聯合表達式相同。查找「Vin Diagrams」和「Union」;避免使用術語組,除非你代表一個組的因素。
http://en.wikipedia.org/wiki/Group_(mathematics)

我覺得你想要表達的是已知組或表中的組;這在wikipedia.org示例D2上。

在這種情況下,這意味着你必須看像一個魔方的問題;並且變得複雜。

我的工作在JavaScript同樣的問題;當我完成我可能會發布它;)。這非常複雜。

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

我修改了上面的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。