2012-02-21 24 views
6

我嘗試縮短我的問題,但這是我能做的最好的。因爲我想這是相當困難的理解我需要什麼,我會提供了一個例子:根據元素的第一個和最後一個值檢測和刪除數組中的元素的最有效方法

說我有以下數組:

$var = array(
    array(1, 2, 3), 
    array(1, 3), 
    array(1, 2, 4, 3), 
    array(1, 3, 4) 
); 

我想是從$var刪除所有陣列具有的第一個和最後一個元素與$var中的另一個數組相同,但元素數量多於後者。

因此,下面陣列應被刪除:(1, 2, 3)(1, 2, 4, 3),因爲它們都開始1並用3結束,並具有比(1, 3),這也開始並以13結束多個元件。 (1, 3, 4)應該保留,因爲沒有其他數組以1開頭並且以4結束並且具有比它少的元素。

我正在尋找最有效的方法來做到這一點,無論是在內存和時間。 $var最多可以有100個陣列,每個陣列最多可以有10個元素。我想過在所有兩個元素之間使用某種比較(for(i=0;...) for(j=i+1;...) complexCompareFunction();),但我認爲這不是非常有效。

+0

你有你想要做什麼用例?可能有更好的方法來實現它... – Josh 2012-02-21 20:23:32

+2

我正在生成鏈接兩個用戶選擇的位置的公共交通線路的所有組合。從生成的行組合(本例中爲'$ var')的數組中,我想刪除那些使用額外行的行。所以,如果可以用'(1,3)'行到達第二個點,爲什麼還要顯示'(1,2,3)'?在這裏,'2'行是額外的,沒有它可以到達目的地。 – linkyndy 2012-02-21 20:27:52

+0

可能旅行1,2,3將花費更少的時間(因爲你坐火車)比1,3(因爲你只能乘坐巴士直接)。我們可以重建問題:以站點作爲節點和連接作爲邊的圖。對於每兩個節點n,m,您現在搜索以n開頭並以m結尾的最短路徑。在這個主題上有大量的參考文獻。 – Basti 2012-02-21 20:41:43

回答

1

一般情況下,是的,你是太擔心效率(正如你在另一評論中所想的那樣)。雖然PHP並不是最快速的語言,但我會建議構建最直接的解決方案,並且只有在最終結果出現明顯問題時纔會優化它或簡化它。

這是我會做的,離開我的頭頂。這是基於阿杰里爾的答案,但希望會更容易遵循,並捕獲一些邊緣案例,這個答案錯過了:

// Assume $var is the array specified in your question 

function removeRedundantRoutes($var){ 

    // This line sorts $var by the length of each route 
    usort($var, function($x, $y){ return count($x) - count($y); }); 

    // Create an empty array to store the result in 
    $results = array(); 

    // Check each member of $var 
    foreach($var as $route){ 
     $first = $route[0]; 
     $last = $route[ count($route) - 1 ]; 
     if(!array_key_exists("$first-$last", $results)){ 
      // If we have not seen a route with this pair of endpoints already, 
      // it must be the shortest such route, so place it in the results array 
      $results[ "$first-$last" ] = $route; 
     } 
    } 

    // Strictly speaking this call to array_values is unnecessary, but 
    // it would eliminate the unusual indexes from the result array 
    return array_values($results); 
} 
+0

通過一些調整,我得到了這個工作。感謝您的幫助和答案中的細節! – linkyndy 2012-02-24 18:29:22

2

使用currentend

$all = array(); 
foreach ($var as $idx=>$arr): 
    $first = current($arr); 
    $last = end($arr); 
    $size = count($arr); 
    $key = $first.'.'.$last; 
    if (isset($all[$key])): 
    if ($size > $all[$key]): 
     unset($var[$idx]); 
    else: 
     $all[$key] = $size; 
    endif; 
    else: 
    $all[$key] = $size; 
    endif; 
endforeach; 

OPS ......你可以遍歷(再次)在年底前確保已減少大小的數組,能夠進一步去除

+0

在這個例子中,'(1,2,3)'仍然存在於數組中。 – 2012-02-21 20:29:08

+0

代碼很好用,但只有'$ var'中的數組是按元素數排序的。我認爲首先按照數組的元素數量排序'$ var'並不是很有效,然後執行你發佈的代碼。還是我太擔心效率? – linkyndy 2012-02-21 20:43:34

+0

在$ all或另一個數組中存儲最小大小的$ idx,併爲其內部的$ idx添加未設置。 – piotrm 2012-02-21 20:49:17

相關問題