2011-07-16 40 views
1

可以說,我有一個數組如下:使用PHP刪除數組中的重複項而不使用任何內置函數?

$sampArray = array (1,4,2,1,6,4,9,7,2,9) 

我要刪除所有來自該陣列的複製,所以結果應該如下:

$resultArray = array(1,4,2,6,9,7) 

但這裏是趕上! !我不想在構建的函數中使用任何PHP,例如array_unique()

你會怎麼做? :)

+4

如何將*你*做呢?你有沒有想過呢? –

+0

想知道爲什麼你不想使用'array_unique()'?學術理由? –

+0

是的。在今天的面試中被問到這個問題。所以,我一直在想,解決問題的最好方法是什麼。 – Scorpyon

回答

1

一個嚴重的(工作)答案:

$inputArray = array(1, 4, 2, 1, 6, 4, 9, 7, 2, 9); 
$outputArray = array(); 

foreach($inputArray as $inputArrayItem) { 
    foreach($outputArray as $outputArrayItem) { 
     if($inputArrayItem == $outputArrayItem) { 
      continue 2; 
     } 
    } 
    $outputArray[] = $inputArrayItem; 
} 
print_r($outputArray); 
+0

是的,它的工作:)我一直在思考。感謝您的回答:) – Scorpyon

+0

我做了一個小的修改,以防止當已經找到重複(內部foreach)時繼續搜索。此外,重複標誌變量不是必需的。 – hakre

0

您可以使用一箇中間數組,依次向其中添加每個項目。在添加項目之前,您可以通過循環遍歷新數組來檢查它是否已經存在。

4

下面是一個簡單的爲O(n) - 時間的解決方案:

$uniqueme = array(); 
foreach ($array as $key => $value) { 
    $uniqueme[$value] = $key; 
} 
$final = array(); 
foreach ($uniqueme as $key => $value) { 
    $final[] = $key; 
} 

你不能有重複鍵,這將保留順序。

+0

注意:只有當值是字符串或整數時纔會工作(即使如此,具有整數值的字符串也不會保留它們的類型,因爲它們會轉換爲整數)。 – Artefacto

+0

@hakre它的確如此。見http://codepad.viper-7.com/fYCvPp – Artefacto

+0

@Artefacto:的確,感謝提示。同樣在這裏:http://codepad.viper-7.com/G6pNpA - 這意味着數組鍵只能用作整數哈希值。我不知道array_merge的行爲如何 - 同樣的:http://codepad.org/3g2Htar4 – hakre

1

編輯2:以下版本使用散列圖來確定值是否已存在。如果這是不可能的,這裏是另一種變體是安全適用於所有PHP的價值觀和做了嚴格的比較(Demo):

$array = array (1,4,2,1,6,4,9,7,2,9); 

$unique = function($a) 
{ 
    $u = array();  
    foreach($a as $v) 
    { 
     foreach($u as $vu) 
      if ($vu===$v) continue 2 
     ; 
     $u[] = $v; 
    } 
    return $u; 
}; 

var_dump($unique($array)); # array(1,4,2,6,9,7) 

編輯:下面相同的版本,但W/O打造功能,只有語言結構(Demo):

$array = array (1,4,2,1,6,4,9,7,2,9); 
$unique = array(); 
foreach($array as $v) 
    isset($k[$v]) || ($k[$v]=1) && $unique[] = $v; 

var_dump($unique); # array(1,4,2,6,9,7) 

而如果你不希望有臨時陣列周圍蔓延,這裏是一個匿名函數的變體:

$array = array (1,4,2,1,6,4,9,7,2,9); 

$unique = function($a) /* similar as above but more expressive ...     ... you have been warned: */ {for($v=reset($a);$v&&(isset($k[$v])||($k[$v]=1)&&$u[]=$v);$v=next($a));return$u;}; 

var_dump($unique($array)); # array(1,4,2,6,9,7) 

首先是讀你不希望使用array_unique或類似功能(array_intersect等),所以這只是一個開始,也許這是SOM使用的還是:

您可以結合使用array_flipPHP Manualarray_keysPHP Manual爲您整數數組(Demo):

$array = array (1,4,2,1,6,4,9,7,2,9); 

$array = array_keys(array_flip($array)); 

var_dump($array); # array(1,4,2,6,9,7) 

由於密鑰只能在PHP數組中存在一次,並且array_flip會保留該命令,因此您將得到結果。由於這些函數的構建速度非常快,並且沒有太多的工作要完成。

+0

「我不想在'array_unique()'」 –

+0

「這樣的構建函數中使用任何PHP,@tandu說,我不想要使用任何內置的函數 – Scorpyon

+0

以及那些函數不像array_unique :)。將顯示相同的W/O任何功能。 – hakre

1

這取決於你有可用的操作。

  • 如果你要檢測是否有重複的是,有兩個元素,並告訴它們是否相等(一個例子是在PHP中==操作)的功能,那麼你必須在每個新的元素與所有的非比較 - 重複您以前找到。解決方案將是二次的,在最壞的情況下(沒有重複),您需要執行(1/2)(n*(n+1))比較。 如果你的數組可以有任何類型的值,這或多或少是唯一可用的解決方案(見下文)。

  • 如果您的值爲total order,可以對數組排序(n*log(n)),然後消除連續的重複項(線性)。請注意,您不能使用PHP中的<>等操作符,它們不會引入全部命令。不幸的是,array_unique會這樣做,並可能因此而失敗。

  • 如果你有一個你可以應用到你的值的散列函數,你可以用散列表(它是數組後面的數據結構)在平均線性時間內完成。查看 tandu的回答。

1
<?php 
$inputArray = array(1, 4, 2, 1, 6, 4, 9, 7, 2, 9); 
$outputArray = array(); 

foreach ($inputArray as $val){ 
if(!in_array($val,$outputArray)){ 
    $outputArray[] = $val; 
} 
} 
print_r($outputArray);