2012-02-21 11 views
6

Sorumu kısaltmaya çalıştım, ancak yapabileceğim en iyi şey budur.Öğelerin ilk ve son değerine göre öğeleri algılama ve kaldırma işlemlerinin en etkili yolu

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

İstediğim olduğunu $var tüm diziler kaldırmaktır:

Aşağıdaki dizi var ki: Ben ihtiyacım olanı anlamak oldukça zor tahmin beri, bir örnek vereceğiz İlk ve son eleman $var'dan başka bir dizi ile aynıdır, ancak ikincisinden daha fazla öğeye sahiptir.

Yani, aşağıdaki diziler kaldırılmalı: (1, 2, 3) ve (1, 2, 4, 3) ikisi de 1 ile başlayıp 3 ile biter ve aynı zamanda başlar ve 1 ve 3 ile biter (1, 3), daha unsurları var çünkü. (1, 3, 4) kalmalıdır, çünkü 1 ile başlayan ve 4 ile biten başka bir dizi yoktur ve bundan daha az öğeye sahiptir.

Bunu yapmanın en etkili yolunu hem bellek hem de zaman açısından arıyorum. $var, en fazla 100 diziye sahip olabilir ve her bir dizi, içinde en fazla 10 öğeye sahip olabilir. İki eleman arasında bir çeşit karşılaştırma yapmayı düşündüm (for(i=0;...) for(j=i+1;...) complexCompareFunction();), ama bunun çok verimli olmadığını düşünüyorum. Kullanım current

+0

yapmanız çalıştığınız şey için bir kullanım durumunda var mı? Uygulamanın daha iyi bir yolu olabilir ... – Josh

+2

Kullanıcı tarafından seçilen iki yeri birbirine bağlayan tüm toplu taşıma hatlarının kombinasyonlarını üretiyorum. Oluşturulan satır kombinasyonları dizisinden (bu durumda '$ var'), ekstra bir çizgi kullananları silmek istiyorum. Yani, eğer ikinci noktaya '(1, 3)' ile ulaşırsa, niçin '(1, 2, 3)' de görüntülenmelidir? Burada, '2' satırı ekstra, o olmadan hedefe ulaşabilirsiniz. – linkyndy

+0

belki de 1,2,3 seyahat etmek için daha az zaman alır (çünkü trenle gidiyorsunuz) 1,3'ten (çünkü sadece otobüsle gidebiliyorsunuz). Sorunu yeniden yapılandırabiliriz: İstasyonları düğümler ve kenarlar olarak bağlantıları ile bir grafiğe sahip olun. Her iki düğüm için n, n ile başlayan ve m ile biten en kısa yolu ararsınız. Bu konuda orada tonlarca referans var. – Basti

cevap

1

Genelde ileri kaldırılan olabilir sağlamak için sonunda (tekrar) yineleme yapabilirsiniz verimlilik hakkında çok endişeli (başka bir yorumda düşündüğünüz gibi). Her ne kadar PHP en hızlı ve hızlı bir dil olmasa da, en basit çözümün oluşturulmasını öneriyorum ve sonuçta göze çarpan bir sorun varsa, onu optimize etmeyi ya da onu iyileştirmeyi dert etmeliyim.

İşte başımın üstünden ne yapardım. Bu ajreal cevabı off dayanır ama umarım izleyin ve bu cevap cevapsız bazı sınır durumları yakalamak daha kolay olacak:

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

Birkaç kez tweaks ile çalışıyorum. Yardımınız ve cevabınızdaki ayrıntılar için teşekkür ederiz! – linkyndy

2

ve end

$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 ... evet, sen, zaten azalmış boyutlu dizi

+0

Bu örnekte '(1, 2, 3)' dizide hala var. –

+0

Kod harika çalışıyor, ancak yalnızca "$ var" dizisindeki öğeler öğelerin sayısına göre sıralanıyorsa. İlk önce dizilerden '$ var' dizisini 'elemanlar' olarak sıralamak ve daha sonra gönderdiğiniz kodu çalıştırmanın çok verimli olmayacağına inanıyorum. Yoksa verimlilik konusunda da endişeli miyim? – linkyndy

+0

$ en küçük boyut için $ idx değerini tüm $ veya diğer bir dizide saklayın ve bu $ idx'in içindeki en dıştaki için unset ekleyin. – piotrm