2016-12-31 5 views
0

これは、繰り返される質問の特定のバリエーションですが、私がそうであるように試みると、スタックオーバーフローのどこでもこの正確な状況を見つけることができませんでした。PHPで特定の回数を繰り返していない組み合わせ。

かいつまんで、私はこのような配列撮りたい:

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

を($日が週の5労働日の任意の数との組み合わせを含めることができます。)

そして、 $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); 
} 

UPDATE:私は助けるために、条件付きで$new_combinationsを割り当てる行をラップしようとしました。理由はわかりませんが、これはまったく効果がありませんでした。繰り返しのあるものであっても、すべての組み合わせが引き続き使用されます。その上

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

そして:そこのような奇妙を返すに

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

出力。

ありがとうございました!

アレックス

+1

繰り返しは何を意味しますか?重複権利。 array_unique($ dayCombinations)を試して、配列を値として扱っているかどうかを確認することはできません。あるいは、 '$ dayCombinations ['Monday-Tuesday'] = array(" Monday "、" Tuesday ");のようにキーとして組み合わせを使用する別の方法は、日が同じであれば自然にユニークですキーの注文。 – ArtisticPhoenix

+0

'$ new_combinations []'割り当ての周りに 'if(!in_array($ item、$ combination))'を追加してください。 – Barmar

+0

バーマー、私は実際にそれを今試みている。サンプリング関数内では、$ combinationと$ charは両方とも文字列なので、strposを使用しようとしています。しかし何らかの理由で運がない。私は今それを反映するためにメインのポストを更新しています。 –

答えて

2

それは日がそれを追加する前に組み合わせて、すでにある場合にだけチェックし、基本的には同じ構造です。順列代わりの組み合わせを返さ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); 
} 

DEMO

+0

私はアイデアが気に入っています。私は、これらが組み合わせではなく順列であることのみを確認しています(たとえば、「月曜日、火曜日」を1つの回答、「火曜日、月曜日」を別のものとします)。私はあなたのコードでそれを理解することができるかどうかを見ていきますが、もしこれを見れば、それに対する迅速な変更はありますか?ありがとう! –

+0

私は呼び出し後にこの部分を修正することができました。後でこれを追加しますが、可能な限り機能するのはやや上手く、効率的です。 \t $ daycombinations = sampling($ dayslisted、$ daysperweek); \t foreachの($キー=> $のdaycombination AS $ daycombinations) \t {\t \tソート($のdaycombination)。 \t \t(in_array($のdaycombination、$ daycombinations)){解除($ daycombinations [$キー]);}もし 他\t \t {$ daycombinations [$キー] = $ daycombination;}} \t –

0

あなたが不要な順列を取り除くために関数を呼び出した後、私は、コードの追加の2行を追加しました。おそらくもっと効率的な方法がありますが、私が見ている配列のサイズは無視できます。下の2行を参照してください。

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)))); 
関連する問題