0

キーがタイムスタンプで、値が ID である配列があります。

例えば:

[11111111] => 11

[12345678] => 21

[12345679] => 4

[12345688] => 2

[22222222] => 1

たとえば、12345677 と 12345689 のような 2 つのタイムスタンプがある場合、これら 2 つの値の間にキーを持つアイテムを見つける最も効果的な方法は何でしょうか? この例では、返されるアイテムは 21、4、および 2 になりますが、大きなデータ セット (200000 以上のアイテム) を扱っているため、効率的である必要があります。

4

1 に答える 1

0
function getMiddlePart($array, $startTime, $tillTime){
    $returnvalues = array();
    asort( $array ); // sort the array (if needed, otherwise remove this)

    // loop forward through the array until proper time is found
    while( key(current($array)) < $startTime){ next($array); } 

    // check if we didnt end at the last one:
    if( key(current($array)) !== key( end($array)){
        // while the $tilltime isnt exeded, store in array:
        while( key(next($array))<= $tillTime){
            $returnvalues[] = current($array); // store current value
        }
    }

    // return array. Can be length===0
    return $returnvalues;
}

next()この関数は、$startTime よりも大きい時間が見つかるまで、配列のポインターを変更することによって機能します。

これを書いているときに、最初のポインターが間違っていることに気づきました。次の編集でそれを修正してください

*ポインターを適切な場所に移動する方法を改善する方法を探しているので、誰か良い提案があれば、コメントに残してください:)


ポインターを簡単に説明するには:
ポインターは、配列内のどこにいるかを記憶するコード内の情報です。配列で何もしない場合、ポインターは最初の項目にあります。でループするとforeach()、ポインターが次の値に設定されます。そのため、そのループで同じ変数名を使用できます。

$array[1] = 'aaa';
$array[2] = 'bbb';
$array[3] = 'ccc';
$array[4] = 'ddd';
$array[5] = 'eee';

echo current($array); // will output: aaa

next(array); // move pointer to the next item
echo current($array); // will now output: bbb

end(array); // set to last item
echo current($array); // will now output: eee

reset(array); // reset, will go back to first item:
echo current($array); // will now output: aaa

これは、非常に大きなデータセットの最速の方法ではありません。次のようなことを数えます。

$curKey = key( current($array) ); // get first key
$arrLength = count($array); 
$offsetLarge = $arrLength * 0.1;  // 10% keys per step
$offsetSmall = $arrLength * 0.05; //  5% keys per step

while( $array[$curKey ] < $startTime ){
    $curKey += $offsetLarge; // INcrease untill limit is met
}
// we are now roughly above it
while( $array[$curKey ] > $startTime ){
    $curKey -= $offsetSmall; // DEcrease untill limit is met
}

//if you want to proceed in smaller steps:
$offsetLarge *= 0.1; // 1% keys per loop
$offsetSmall *= 0.1; // 1% keys per loop
while( $array[$curKey ] < $startTime ){
    $curKey += $offsetLarge; // INcrease untill limit is met
}
// we are now roughly above it
while( $array[$curKey ] > $startTime ){
    $curKey -= $offsetSmall; // DEcrease untill limit is met
}
// At this point you are very close ($curKey) should be just below it and can loop up till found value. 
于 2013-09-19T16:50:08.683 に答える