2012-02-21 5 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で始まり、4で終わり、それよりも少ない要素があるため、(1, 3, 4)は残ります。

私は、メモリと時間の両方でこれを行う最も効率的な方法を探しています。 $varには最大100個のアレイがあり、個々のアレイには最大10個の要素が含まれます。私は2つの要素(for(i=0;...) for(j=i+1;...) complexCompareFunction();)の間の何らかの比較を使用することを考えましたが、これはあまり効率的ではないと私は信じています。

+0

あなたが何をしようとしてのためのユースケースを持っていますか?それを実装するより良い方法があるかもしれません... – Josh

+2

私は、2つのユーザが選択した場所をリンクする公共交通機関のすべての組み合わせを生成しています。生成された行の組み合わせ(この場合は '$ var')から、余分な行を使用する行を削除したいと思います。だから、 '(1,3)'という行で2番目のポイントに到達できるのであれば、なぜ '(1,2,3)'も表示すべきでしょうか?ここでは、行「2」は余分であり、1つは宛先なしに到達することができます。 – linkyndy

+0

おそらく1,2,3は1,3よりも(列車で行くので)時間がかかりません(バスで直接行くことができるからです)。私たちは問題を再構築することができます。ステーションをノードとして、グラフをエッジとして接続します。 2つのノードn、mごとに、nで始まりmで終わる最短パスを検索します。このトピックにはそこにたくさんの参考文献があります。 – Basti

答えて

1

を削除することができ確実にするために最後に(再び)反復することができ、はい、あなたは、効率性をあまりにも心配しました(あなたが別のコメントで不思議に思ったように)。 PHPは最も洗練された言語ではありませんが、私は最も単純なソリューションを構築することを推奨し、最終的な結果に目立った問題がある場合には、最適化や簡素化を心配しています。

私の頭の上から、私がやることです。それはajrealの答えをベースにしていますが、うまくいけば従うことが容易になり、そしてその答えは逃したいくつかのエッジケースをキャッチします:

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

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; 

オプス...あなたはすでに減少サイズの配列がさらに一般的には

+0

この例では、 '(1,2,3)'はまだ配列に存在します。 –

+0

コードは素晴らしいですが、 '$ var'内の配列が要素数でソートされている場合に限ります。配列の要素数で '$ var'を最初に並べ替えた後、投稿したコードを実行するのは効率的ではないと思います。あるいは私は効率についてあまりにも心配していますか? – linkyndy

+0

$ allまたは他の配列に最小サイズの$ idxを格納し、この$ idxの中で最も内側のものにunsetを追加します。 – piotrm

関連する問題