12
これは、にラップアラウンドできるという事実を表現する方法を理解すれば簡単に実行できます1
。
これが私の解決策です。着信配列を自然にソートしてから、$months
次のような配列を作成します。
$months = 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
その配列から、入力配列をループして、月の値が設定されていない場所にゼロを配置します。したがって、の入力配列を使用するarray( 1, 2, 11, 12)
と、$inputs
配列は次のようになります。
$inputs = 1 2 0 0 0 0 0 0 0 0 11 12 1 2 0 0 0 0 0 0 0 0 11 12
ここから、アルゴリズムは単純です。$inputs
配列をループして、0ではない最長のシーケンスを見つけます。これにより、可能なすべてのシーケンシャルシーケンスが生成されます。
function sort_months( $array)
{
natsort( $array);
$keys = array_flip( $array);
$inputs = array();
$months = array_merge( range( 1, 12), range( 1, 12));
foreach( $months as $m) {
$inputs[] = (isset( $keys[$m])) ? $m : 0;
}
$sequences = array();
for( $i = 0, $ii = count( $inputs); $i < $ii; $i++) {
if( $inputs[$i] != 0) {
$sequence = array( $inputs[$i]);
for( $k = $i + 1, $kk = $ii + 1; $k < $kk; $sequence[] = $inputs[$k], $k++) {
if( !isset( $inputs[$k]) || $inputs[$k] == 0) {
break;
}
}
$sequences[] = $sequence;
}
}
return $sequences;
}
入力するarray( 12, 11, 1, 2)
と、これは以下を出力します:
array(8) {
[0]=>
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
[1]=>
array(1) {
[0]=>
int(2)
}
[2]=>
array(4) {
[0]=>
int(11)
[1]=>
int(12)
[2]=>
int(1)
[3]=>
int(2)
}
[3]=>
array(3) {
[0]=>
int(12)
[1]=>
int(1)
[2]=>
int(2)
}
[4]=>
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
[5]=>
array(1) {
[0]=>
int(2)
}
[6]=>
array(2) {
[0]=>
int(11)
[1]=>
int(12)
}
[7]=>
array(1) {
[0]=>
int(12)
}
}
最長のシーケンシャルシーケンスが実際に(他のすべての可能なシーケンスとともに)配列に存在することがわかります。
[2]=>
array(4) {
[0]=>
int(11)
[1]=>
int(12)
[2]=>
int(1)
[3]=>
int(2)
}
関数に入力されたすべての月を表す、使用するシーケンスを選択する方法を決定するのはOPに任せています。