2011-06-22 48 views
4

對於在數組中進行快速搜索有什麼更好的方法存在疑問(我正在談論一個特定的案例)。在陣列中進行PHP in_array和快速搜索(最後)

因爲我有一個數組L = [A,B,C](當我開始時)。當程序運行時,可能L會增長(但到最後),當我執行搜索時,一種可能的情況是L = [A,B,C,D,E]。

事實是,當我搜索時,我想要查找的值可能只有D和E.現在我使用find_array(elem,array),但是此函數不能被「調整」爲搜索從最後開始並減少索引,我「擔心」,對於所有搜索,in_array函數將檢查所有具有較低索引的元素,然後纔會查找我正在搜索的值。

¿還有另一種搜索功能更適合我的問題? ¿如何在in_array函數內部工作?

預先感謝

+0

在旁註:如果您事先知道您只會搜索新值?難道不可能將這些新值存儲在一個單獨的數組中,這個數組會更小,因此可以更快地搜索? (如果kenforces的答案不適合你) – Yoshi

+0

我使用get_declared_classes()函數,並且我必須發現是否加載了特定的類... – castarco

+0

php手冊沒有提及函數find_array( )。所以我想知道你是否想要找到的元素的關鍵,或者如果你只是想知道元素是否存在。 – Leif

回答

8

我假定in_array是從0到n-1的線性搜索。

最快的搜索是將值存儲爲密鑰並使用array_key_exists

$a['foo'] = true; 
$a['bar'] = true; 

if (array_key_exists('foo', $a)) ... 

但如果這不是一種選擇,你可以讓你自己的索引數組非常容易:

function in_array_i($needle, array $a, $i = 0); 
{ 
    $c = count($a); 
    for (;$i < $c; ++$i) 
    if ($a[$i] == $needle) return true; 
    return false; 
} 

它將開始在$i,你可以跟蹤自己,以跳過第一要素。

或可替代...

function in_array_i($needle, array $a, $i = 0); 
{ 
    return in_array($needle, $i ? array_slice($a, $i) : $a); 
} 

您可以基準,看看哪個更快。

+0

我會標準寫在這裏:)。 – castarco

+0

我認爲它會變慢,因爲in_array是用c編寫的... –

+1

['isset()'會更快。](http://stackoverflow.com/questions/700227/whats-quicker-and-better-to -determine-if-an-array-key-exists-in-php) –

2

至於你的評論,你可以這樣做:

$classes = array_flip(get_declared_classes()); 
$check = isset($classes['%someClassName%']); 

這可能會快很多那麼任何價值的搜索。

+0

它不僅可能*但更快。然而,它無法搜索「NULL」值,並且它在重複值上失敗。 – hakre

+1

@hakre是啊:)但考慮到'get_declared_classes()'既不包含NULL也不重複,我認爲在這個特定情況下這不是一個真正的問題。 – Yoshi

+0

對,不是那種情況:)但是可能'class_exists('%someClassName%')'更快。 ;) – hakre

0

如何在in_array函數內部工作?

Internallyin_array()從數組的開頭到末尾的搜索。所以你的情況很慢。

根據數據的性質,您可以更改搜索策略。如果只有非重複值和所有值都是字符串或整數(而不是NULL),則常見技巧是array_flip()該數組運行速度非常快,然後檢查是否有值的條目作爲鍵在通過isset()數組哈希:

$array = array(... non-duplicate string and integer values ...); 
    $needle = 'find me!'; 
    $lookup = array_flip($array); 
    $found = isset($lookup[$needle]) ? $lookup[$needle] : false; 
    if (false === $found) { 
    echo "Not found!\n"; 
    } else { 
    echo "Found at {$found}!\n"; 
    } 

如果這些前提條件得不到滿足,你可以做什麼konforce建議。

如果你有非常多的數據,而且不僅僅是你從開始或結束看,你可能想要自己實現一個搜索算法,就像從開始和結束開始一樣,但是包裝和/或從隨機位置開始分配搜索時間。

此外,您可以保留元素排序,同時添加到數組中,然後可以使用擬合算法更快地搜索元素。