2012-02-21 48 views
6

Tôi đã thử rút ngắn câu hỏi của mình, nhưng đây là cách tốt nhất tôi có thể làm. Kể từ khi tôi đoán nó là khá khó khăn để hiểu những gì tôi cần, tôi sẽ cung cấp một ví dụ:Cách hiệu quả nhất để phát hiện và loại bỏ các phần tử trong mảng dựa trên giá trị đầu tiên và cuối cùng của các phần tử

Nói rằng tôi có các mảng sau:

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

Những gì tôi muốn là để loại bỏ tất cả các mảng từ $var rằng có phần tử đầu tiên và cuối cùng giống với một mảng khác từ $var nhưng có nhiều phần tử hơn phần tử thứ hai.

Vì vậy, các mảng sau đây cần được loại bỏ: (1, 2, 3)(1, 2, 4, 3) vì cả hai đều bắt đầu với 1 và kết thúc bằng 3 và có những yếu tố hơn (1, 3), mà còn bắt đầu và kết thúc với 13. (1, 3, 4) nên vẫn còn, vì không có mảng nào khác bắt đầu bằng 1 và kết thúc bằng 4 và có ít thành phần hơn.

Tôi đang tìm cách hiệu quả nhất để thực hiện việc này, cả về bộ nhớ và thời gian. $var có thể có tối đa 100 mảng và mỗi mảng riêng lẻ có thể có tối đa 10 phần tử trong đó. Tôi nghĩ về việc sử dụng một số loại so sánh giữa tất cả hai yếu tố (for(i=0;...) for(j=i+1;...) complexCompareFunction();), nhưng tôi tin rằng điều này không phải là rất hiệu quả.

+0

Bạn có trường hợp sử dụng cho những gì bạn đang cố gắng làm không? Có thể có cách tốt hơn để thực hiện nó ... – Josh

+2

Tôi đang tạo tất cả các kết hợp của các tuyến giao thông công cộng liên kết hai địa điểm do người dùng chọn. Từ mảng kết hợp dòng được tạo ra ('$ var' trong trường hợp này), tôi muốn xóa các kết hợp có sử dụng dòng thừa. Vì vậy, nếu người ta có thể đạt đến điểm thứ hai với các dòng '(1, 3)', tại sao nên '(1, 2, 3)' cũng được hiển thị? Ở đây, dòng '2' là phụ, người ta có thể đến đích mà không có nó. – linkyndy

+0

có thể để đi 1,2,3 sẽ mất ít thời gian hơn (vì bạn đi bằng tàu hỏa) hơn 1,3 (vì bạn chỉ có thể đi bằng xe buýt trực tiếp). chúng ta có thể tái tạo lại vấn đề: có một đồ thị với các trạm như các nút và các kết nối như các cạnh. cho mỗi hai nút n, m bạn bây giờ tìm kiếm đường đi ngắn nhất bắt đầu bằng n và kết thúc bằng m. có rất nhiều tài liệu tham khảo ngoài chủ đề này. – Basti

Trả lời

1

Nói chung, vâng, bạn có quá lo lắng về hiệu quả (như bạn đã tự hỏi trong một bình luận khác). Mặc dù PHP không phải là ngôn ngữ nhanh nhất, tôi khuyên bạn nên xây dựng giải pháp đơn giản nhất, và chỉ lo lắng về việc tối ưu hóa nó hoặc tinh giản nó nếu có một vấn đề đáng chú ý với kết quả cuối cùng.

Đây là những gì tôi sẽ làm, ngoài đỉnh đầu của tôi. Nó được dựa trên câu trả lời của ajreal nhưng hy vọng sẽ dễ dàng hơn để theo dõi, và bắt một số trường hợp cạnh mà câu trả lời bị mất:

// 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

Với một vài điều chỉnh, tôi đã làm việc này. Cảm ơn sự giúp đỡ của bạn và cho các chi tiết trong câu trả lời của bạn! – linkyndy

2

sử dụng 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 ... bạn có thể lặp (một lần nữa) ở cuối để đảm bảo các mảng có kích thước đã giảm có thể được tiếp tục loại bỏ

+0

Trong ví dụ này, '(1, 2, 3)' vẫn tồn tại trong mảng. –

+0

Mã hoạt động rất tốt, nhưng chỉ khi các mảng bên trong '$ var' được sắp xếp theo số phần tử. Tôi tin rằng sẽ không có hiệu quả khi sắp xếp đầu tiên '$ var' theo số lượng các phần tử của mảng, và sau đó thực thi mã mà bạn đã đăng. Hay tôi quá lo lắng về hiệu quả? – linkyndy

+0

Lưu trữ $ idx cho kích thước nhỏ nhất trong $ all hoặc một mảng khác và thêm unset cho $ idx này bên trong cùng một vị trí khác. – piotrm

Các vấn đề liên quan