每週一道算法題006:抽籤組合

問題:

有如下3支隊伍,每個隊伍都有2名隊員。
team1:A,B;
team2:C,D;
team3:E,F;

現在每個隊出1個人,組成一個隊去探險,請列出所有的組隊方式。

思路:

這就是一個組合的問題,每個隊裏挑一人,那麼總共應該有222=8種組合方式。
如果暴力求解,那就是三層循環嵌套。但如果問題擴展一下,變成10個隊,每個隊10人,就無法暴力求解了,至少代碼是沒有擴展性的。

有如下一種思路:

循環所有的隊伍
第一次取出A,B兩名隊員,存起來;
第二次取出C,D兩名隊員,與前一輪存下的隊員進行交叉組合,得到AC,AD,BC,BD4種組合,再存起來;
第三次取出E,F兩名隊員,再與前一輪存下的結果進行交叉組合,得到ACE,ACF,ADE,ADF,BCE,BCF,BDE,BDF。
以此類推。

每一次循環都將前本輪的隊員與前一輪的隊員進行組合,直到將所有的組合遍歷完畢。

解答:

php

<?php
function getCombinations($arrays) {
    $result = array(array());
    foreach ($arrays as $property => $property_values) {
        $tmp = array();
        foreach ($result as $result_item) {
            foreach ($property_values as $property_value) {
                $tmp[] = array_merge($result_item, array($property => $property_value));
            }
        }
        $result = $tmp;
    }
    return $result;
}

$combinations = getCombinations(
    array(
        'item1' => array('A', 'B'),
        'item2' => array('C', 'D'),
        'item3' => array('E', 'F'),
    )
);
$rs = $combinations;
print_r($rs);

輸出:

Array
(
    [0] => Array
        (
            [item1] => A
            [item2] => C
            [item3] => E
        )

    [1] => Array
        (
            [item1] => A
            [item2] => C
            [item3] => F
        )

    [2] => Array
        (
            [item1] => A
            [item2] => D
            [item3] => E
        )

    [3] => Array
        (
            [item1] => A
            [item2] => D
            [item3] => F
        )

    [4] => Array
        (
            [item1] => B
            [item2] => C
            [item3] => E
        )

    [5] => Array
        (
            [item1] => B
            [item2] => C
            [item3] => F
        )

    [6] => Array
        (
            [item1] => B
            [item2] => D
            [item3] => E
        )

    [7] => Array
        (
            [item1] => B
            [item2] => D
            [item3] => F
        )

)

golang:

package main

import "fmt"

func main() {
    // 三組數據,每組選一個進行組合,總數應是2*2*2
    d := make(map[string][]string)
    d["item1"] = []string{"A", "B"}
    d["item2"] = []string{"C", "D"}
    d["item3"] = []string{"E", "F"}

    rs := getCombinations(d)
    fmt.Println(rs)
}

// 取得組合列表
func getCombinations(data map[string][]string) [][]map[string]string {
    result := make([][]map[string]string, 1)
    for property, propertyValues := range data {
        tmp := make([][]map[string]string, 0)
        for _, resultItem := range result {
            for _, propertyValue := range propertyValues {
                tmp = append(tmp, append(resultItem, map[string]string{property: propertyValue}))
            }
        }
        result = tmp
    }
    return result
}

輸出:(格式略作調整)

[[map[item1:A] map[item2:C] map[item3:E]]
[map[item1:A] map[item2:C] map[item3:F]] 
[map[item1:A] map[item2:D] map[item3:E]] 
[map[item1:A] map[item2:D] map[item3:F]] 
[map[item1:B] map[item2:C] map[item3:E]] 
[map[item1:B] map[item2:C] map[item3:F]]
[map[item1:B] map[item2:D] map[item3:E]]
[map[item1:B] map[item2:D] map[item3:F]]]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章