2017-01-14 6 views
0

O(n)よりも素早く要素を見つけることができるデータ構造またはソリューションを探しています見つかった要素の前の要素を取得しますリスト内の要素を検索して前の要素を取得する(両方とも高速である必要があります)

私のケースでは、が既に埋め込まれてソートされています。、DateTimeで要素を見つける必要があり、以前のx要素を返す必要があります。

私はLinkedListで試しましたが、検索が遅すぎましたo(n)。 私はDateTimeで見つけることができるように辞書を使うことも考えましたが、前の要素を得るために逆順にループする方法はわかりません。

class FinancialQuote 
{ 
    public DateTime TradingDate; 
    public double Price; 

    protected bool Equals(FinancialQuote other) 
    { 
     return TradingDate.Equals(other.TradingDate); 
    } 
} 

public void Main() 
{ 

    var quotes = new LinkedList<FinancialQuote>(); 
    // quotes are populated here 

    var result = new List<FinancialQuote>(); 
    var howManyQuotes = 2; 

    // the goal here is to find quote4 and returns quote3 and quote2 
    var currentNode = quotes.Find(quote4); // O(N) which is too slow 

    for (int i = 0; i < howManyQuotes; i++) 
    { 
     var previousClose = currentNode.Previous.Value; 
     result.Add(previousClose); 

     currentNode = currentNode.Previous; 
    } 
} 

だから私の変数をもたらすはずがquote3とquote2

+0

*既に入力されてソートされています。あなたが後で検索する必要がある 'TradingDate'によって? –

+1

BinarySearchを使用するよりも索引付けが速くなりますが、設定に時間がかかり、明らかにそれ以上のスペースが必要な場合は、そのような辞書を使用しても問題ありません。あなたが何を求めているのか分かりません。 E:基本的にLinkedListの使用をやめてください。私は文字通りそれが有用であることを見たことはありません。オーバーヘッドは、ほとんどすべてのケースで一定の時間の挿入と削除の利点を上回ります。 – harold

+0

@harold:1)辞書を通って前方/後方にループすることは自明ではありません。 2)「ほぼすべての場合」の「LinkedList」オーバーヘッドに関する記述は理解できません。長所と短所はよく知られています。何度も挿入したり削除したりするための構造が必要で、巨大なリストを扱っているのなら、それは*選択構造です。 – Lou

答えて

0

が含まれていますが、日付でソートされている必要があり、通常のList<FinancialQuote>使用する必要があります。

BinarySearchを使用して、DateTimeを挿入するインデックスを指定します。リスト作成にもこの機能を使用してください。これは、dateTimeが見つかった場合は正のインデックス(完全一致)を返し、このdatetimeを挿入する必要がある負のインデックスを返します。

このインデックスを上限として使用します。 (検索されたインデックスに0を反復する)

2

Listタイプは、すでにインデックスで要素にアクセスするためのO(1)時間を保証します。したがって、バイナリ検索アルゴリズムを適用してソートされたリストの要素を見つけるためにO(logN)時間を達成することができます。

その後、その要素の先祖を繰り返し処理するだけで済みます。

int index = quotes.BinarySearch(searchValue); 

if (index >= 0) 
{ 
    int lowIndex = Math.Max(index - howManyQuotes, 0); 
    for (int cur = lowIndex; cur <= index; cur++) 
    { 
     // do something with quotes[cur]; 
    } 
} 
+0

+1でもOPは正確な一致がないと何が起きるのかを明確にするべきです( 'BinarySearch'は最初の大きなインデックスのビット補数を返すので、おそらくこのメソッドはまだ何らかの結果を取得できます)。 – Lou

+0

それは本当です。私は潜在的な例外から守るだけです。 –

+0

リストが正しくソートされていれば(これは疑問からは分かりませんが)、これは確かに解決策ですが、 'BinarySearch'は直接プロパティ値を検索することはできません。だからそれはカスタムバイナリ検索方法でなければなりませんが、原則は同じです。 –