PHP中特定计数的非重复组合

时间:2016-12-31 20:22:16

标签: php arrays algorithm statistics combinations

这是经常重复的问题的一个特殊变体,但尽可能尝试,我无法在Stack Overflow上找到这种确切的情况。

长话短说,我想采取这样的数组:

$days[0] = 'Monday';
$days[1] = 'Tuesday';
$days[2] = 'Thursday';

($ days可以包含一周中五个工作日的任何数字和组合。)

然后,给定$numberOfDays的特定值(当然,必须至少为1且不超过$days的数量),我想要一个数组包含$ daysOfDays天数$天的所有可能组合。

例如:

$days[0] = 'Monday';
$days[1] = 'Tuesday';
$days[2] = 'Thursday';

$numberOfDays = 2;

$dayCombinations = getDayCombinations($days, $numberOfDays);

输出:

$dayCombinations[0] = array("Monday", "Tuesday");
$dayCombinations[1] = array("Monday", "Thursday");
$dayCombinations[2] = array("Tuesday", "Thursday");

请注意,这些是组合,而不是排列,因此顺序并不重要。

如果有帮助,我发现这个函数here: 它工作得很好,但包括重复,并且基于字符串而不是数组(最后一部分是可行的,不是很重要,但重复部分真的让我感到困惑)。

function sampling($chars, $size, $combinations = array()) {

    # if it's the first iteration, the first set 
    # of combinations is the same as the set of characters
    if (empty($combinations)) {
        $combinations = $chars;
    }

    # we're done if we're at size 1
    if ($size == 1) {
        return $combinations;
    }

    # initialise array to put new values in
    $new_combinations = array();

    # loop through existing combinations and character set to create strings
    foreach ($combinations as $combination) {
        foreach ($chars as $char) {
            $new_combinations[] = $combination . $char;
        }
    }

    # call same function again for the next iteration
    return sampling($chars, $size - 1, $new_combinations);
}

更新:我已经尝试将$new_combinations行分配给有条件的帮助;这根本没有效果,虽然我不确定为什么。所有的组合仍然存在,即使是重复的组合。

function sampling($chars, $size, $combinations = array()) {

    # if it's the first iteration, the first set 
    # of combinations is the same as the set of characters
    if (empty($combinations)) {
        $combinations = $chars;
    }

    # we're done if we're at size 1
    if ($size == 1) {
        return $combinations;
    }

    # initialise array to put new values in
    $new_combinations = array();

    # loop through existing combinations and character set to create strings
    foreach ($combinations as $combination) {
        foreach ($chars as $char) {
            if (strpos($combination, $char) === FALSE) {
                echo "Char $char not found in Combination $combination<br>";
                $new_combinations[] = $combination . $char;
            }
        }
    }

    # call same function again for the next iteration
    return sampling($chars, $size - 1, $new_combinations);
}

那里的输出会返回奇怪的内容,如:

Char 2 not found in Combination 2
Char 3 not found in Combination 23

等等。

感谢您的帮助!

亚历

2 个答案:

答案 0 :(得分:2)

它基本上是相同的结构,只需在添加之前检查日期是否已经在组合中。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/combo_hovered" android:state_hovered="true"></item>
    <item android:drawable="@drawable/combo_pressed" android:state_activated="true"></item>
    <item android:drawable="@drawable/combo_pressed" android:state_pressed="true"></item>
    <item android:drawable="@drawable/combo_unpressed"></item>

</selector>

python-minimal

答案 1 :(得分:0)

撇开Barmar的回答,它返回了排列而不是组合,我在调用函数后添加了另外两行代码来摆脱不必要的排列。可能有一种更有效的方法,但对于阵列大小我看它可以忽略不计。见下面的最后两行。

function sampling($days, $size, $combinations = array()) {

    # if it's the first iteration, the first set 
    # of combinations is the same as the set of days
    if (empty($combinations)) {
        $combinations = array_map(function($day) { return array($day); }, $days);
    }

    # we're done if we're at size 1
    if ($size == 1) {
        return $combinations;
    }

    # initialise array to put new values in
    $new_combinations = array();

    # loop through existing combinations and character set to create strings
    foreach ($combinations as $combination) {
        foreach ($days as $day) {
            if (!in_array($day, $combination)) {
                $new_combination = $combination;
                $new_combination[] = $day;
                $new_combinations[] = $new_combination;
            }
        }
    }

    # call same function again for the next iteration
    return sampling($days, $size - 1, $new_combinations);
}

$combinations = getDayCombinations($days, $numberOfDays);

for ($round=0;$round<count($combinations);$round++){sort($combinations[$round]);}
    $combinations = array_values(array_map("unserialize", array_unique(array_map("serialize", $combinations))));