4

次のような形式のデータのいくつかの異なるテーブルがある職場でのシナリオがあります。

Table Name: HingeArms
Hght   Part #1       Part #2
33     S-HG-088-00   S-HG-089-00
41     S-HG-084-00   S-HG-085-00
49     S-HG-033-00   S-HG-036-00
57     S-HG-034-00   S-HG-037-00

最初の列 (および場合によってはそれ以上) には、昇順に並べ替えられた数値データが含まれ、取得するデータの適切なレコードを決定する範囲を表します (たとえば、高さ <= 33 の場合、パート 1 = S-HG-088-00、高さ <= 41 の場合1部=S-HG-084-00など)

指定された値を指定して、最も近い一致を検索して選択する必要があります。たとえば、高さが 34.25 の場合、上記のセットの 2 番目のレコードを取得する必要があります。

41     S-HG-084-00   S-HG-085-00

これらのテーブルは現在、CSV ファイルからロードされたデータの VB.NET ハッシュテーブル "キャッシュ" に格納されています。ハッシュテーブルのキーは、テーブル名と、テーブルの "キー" を表すテーブルの 1 つ以上の列を組み合わせたものです。記録。たとえば、上記のテーブルの場合、最初のレコードの Hashtable Add は次のようになります。

ht.Add("HingeArms,33","S-HG-088-00,S-HG-089-00")

これは最適とは言えず、必要に応じて構造を柔軟に変更できます (キャッシュには、直接参照が可能な他のテーブルからのデータが含まれています... これらの「範囲」テーブルは、「簡単」だったためにダンプされました)。範囲内で最も一致するレコードを取得するために Hashtable/Dictionary の "Next" メソッドを探していましたが、VB.NET のストック クラスでは明らかに利用できません。

ハッシュテーブルまたは別の構造で探していることを行う方法についてのアイデアはありますか? ルックアップはコードのさまざまなセクションで頻繁に呼び出されるため、パフォーマンスが高い必要があります。どんな考えでも大歓迎です。ありがとう。

4

3 に答える 3

4

ハッシュテーブルは、これには適したデータ構造ではありません。アイテムは、値ではなく、ハッシュ コードに従って内部配列に散らばっているためです。

ソートされた配列またはList<T>を使用して、バイナリ検索を実行します。

設定:

var values = new List<HingeArm>
{
    new HingeArm(33, "S-HG-088-00", "S-HG-089-00"),
    new HingeArm(41, "S-HG-084-00", "S-HG-085-00"),
    new HingeArm(49, "S-HG-033-00", "S-HG-036-00"),
    new HingeArm(57, "S-HG-034-00", "S-HG-037-00"),
};

values.Sort((x, y) => x.Height.CompareTo(y.Height));

var keys = values.Select(x => x.Height).ToList();

調べる:

var index = keys.BinarySearch(34.25);
if (index < 0)
{
    index = ~index;
}

var result = values[index];
// result == { Height = 41, Part1 = "S-HG-084-00", Part2 = "S-HG-085-00" }
于 2012-05-07T18:20:24.497 に答える
0

LINQ-to-Objects はどうですか (これは決してパフォーマンスの高いソリューションを意図したものではありません)。


    var ht = new Dictionary<string, string>();
    ht.Add("HingeArms,33", "S-HG-088-00,S-HG-089-00");
    decimal wantedHeight = 34.25m;

    var foundIt =
        ht.Select(x => new { Height = decimal.Parse(x.Key.Split(',')[1]), x.Key, x.Value }).Where(
            x => x.Height < wantedHeight).OrderBy(x => x.Height).SingleOrDefault();

    if (foundIt != null)
    {
        // Do Something with your item in foundIt
    }
于 2012-05-07T18:21:04.737 に答える
0

並べ替えられた .NET 配列を Array.BinarySearch() と組み合わせて使用​​できます。負でない値を取得した場合、これは完全一致のインデックスです。それ以外の場合、結果が負の場合は数式を使用します

int index = ~Array.BinarySearch(sortedArray, value) - 1

以前の「最も近い」一致のインデックスを取得します。

Nearest の意味は、使用する比較子によって定義されます。配列をソートするときに使用したものと同じでなければなりません。見る:

http://gmamaladze.wordpress.com/2011/07/22/back-to-the-roots-net-binary-search-and-the-meaning-of-the-negative-number-of-the-array-二分探索の戻り値/

于 2012-05-07T18:42:05.057 に答える