14

オブジェクトが関連付けられているフロート キーでオブジェクトを並べ替えることができるデータ構造が必要です。問題は、キーがコストを表すため、重複することが多いことです.2つのコストが同じ場合、違いがないため最初のものを取得するだけなので、これは気にしません.問題は、コンパイラが文句を言うことです.

同じように動作するが重複キーを許可するデータ構造はありますか?

編集 - ただし、1 つが行き止まりであることが判明した場合は、次のものを取得するため、まだ重複が必要です (それらは a* 検索のノードです)。

明確にするために、順番に並べ替えられた重複キーを許可する必要があります。

4

9 に答える 9

12

あなたが書く:

重複キーを許可する辞書と同等

オブジェクトが関連付けられている float キーでオブジェクトを並べ替えることができるデータ構造が必要です。

ディクショナリはキーでソートされたアイテムを保持しないため、探している構造は実際には aDictionaryとまったく同等ではありません。必要なのは、キーの重複を許可する必要があることを除いて、 SortedListorに似たものです。SortedDictionary

そのようなクラスは .NET には存在しません。ただし、いくつかのオプションがあります。

  • 通常は最初の値のみが必要SortedDictionary<double, List<TValue>>ですが、キーに関連付けられたすべての値を保存する場合に使用します。初めてキーを挿入するときは、新しいリストを作成し、リストに値を追加します。既に存在するキーを挿入する場合は、リストを取得して値をリストに追加します。
  • あなたの編集は、このアプローチがあなたの状況には当てはまらないことを意味します。 挿入する前に重複を使用して確認してください。SortedDictionary<double, TValue>各キーの最初の値のみが保存されるため、上記のアプローチとは異なり、この方法では 2 番目の値にまったくアクセスできません。
  • 必要な処理を行うクラスを含むサード パーティのコレクション ライブラリを見つけます。

関連している

于 2012-08-03T18:37:10.910 に答える
7

以下から派生する独自のクラスを作成できますSortedSet

public class SortedTupleBag<TKey, TValue> : SortedSet<Tuple<TKey, TValue>> 
    where TKey : IComparable
{
    private class TupleComparer : Comparer<Tuple<TKey, TValue>>
    {
        public override int Compare(Tuple<TKey, TValue> x, Tuple<TKey, TValue> y)
        {
            if (x == null || y == null) return 0;

            // If the keys are the same we don't care about the order.
            // Return 1 so that duplicates are not ignored.
            return x.Item1.Equals(y.Item1)
                ? 1
                : Comparer<TKey>.Default.Compare(x.Item1, y.Item1);
        }
    }

    public SortedTupleBag() : base(new TupleComparer()) { }

    public void Add(TKey key, TValue value)
    {
        Add(new Tuple<TKey, TValue>(key, value));
    }
}

コンソールアプリでの使用法:

private static void Main(string[] args)
{
    var tuples = new SortedTupleBag<decimal, string>
    {
        {2.94M, "Item A"}, 
        {9.23M, "Item B"}, 
        {2.94M, "Item C"}, 
        {1.83M, "Item D"}
    };

    foreach (var tuple in tuples)
    {
        Console.WriteLine("{0} {1}", tuple.Item1, tuple.Item2);
    }

    Console.ReadKey();
}

この結果を生成します:

 1.83 Item D
 2.94 Item A
 2.94 Item C
 9.23 Item B
于 2013-03-15T18:54:27.477 に答える
6

私はこの問題に何度も遭遇しましたが、常に Wintellect ( http://powercollections.codeplex.com ) のパブリック ライセンス (つまり無料) の Power Collection を使用しています。まさにあなたが探しているものである OrderedMultiDictionary があります。重複キーが許可され、すべての重複キー エントリを反復処理できます。

于 2013-05-08T22:04:37.997 に答える
3

あなたはルックアップを探しています。すでに提案されている他の辞書ベースのソリューションと同様に、重複を処理するために各キーの下にIEnumerableを格納します。

var registry = Items.ToLookup(item=>item.Price);
foreach(var item in registry[desiredPrice])
{
     //Here you handle items that all have Price == desiredPrice
}
于 2012-08-03T18:35:42.017 に答える
2

CompareTo 関数をオーバーライドすることで実行できます。aelement を SortedDictionary に追加すると、CompareTo() が使用され、結果が 0 の場合は例外が発生しますが、キー クラス実装のコンパレータの動作を変更して、より大きいか小さい (1 または -1) のみを返すようにすることができます。

        public int CompareTo(int key)
    {
        if (this.key.CompareTo(key) < 1)
            return 1;
        else
            return -1;
    }
于 2016-03-06T19:51:07.773 に答える
1

あなたはまだ辞書を使うことができます。値のタイプを単一のアイテムではなくコレクションに変更する必要があります。

Dictionary<float, List<T>>

辞書be定義では、重複キーは許可されていません。

于 2012-08-03T18:35:13.107 に答える
1

あなたが話しているのはバッグです。バッグセットの違いは、セットは一意であるのに対し、バッグは複製できることです。{a,b,c} はセットです。{a,b,c,a} はバッグです。

C5 Collections Libraryのコピーを入手してください。クラスHashBag<T>またはが必要TreeBag<T>です。違いは、基になるデータ ストアが一方はハッシュであり、もう一方は赤黒ツリーであることです。外部的には、それらは同じように動作します。どちらかがあなたが望むものをあなたに与えるはずです。

于 2012-08-03T18:46:59.897 に答える
0

探しているものは aheapまたはと呼ばれpriority queueます。Googleで検索すると、C#用のものが見つかると確信しています

于 2012-08-03T18:33:08.820 に答える
0

衝突を避けるために、IComparer のカスタム実装で SortedDictionary を使用できるはずです。例えば:

private class NonCollidingFloatComparer : IComparer<float>
{
    public int Compare(float left, float right)
    {
        return (right > left) ? -1 : 1; // no zeroes 
    }
}

// silly method for the sake of demonstration
public void sortNodes(List<Node> nodesToSort)
{
    SortedDictionary<float, Node> nodesByWeight = new SortedDictionary<float, Node>(new NonCollidingFloatComparer());
    foreach (Node n in nodesToSort)
    {
        nodesByWeight.Add(n.FloatKey, n);
    }
    foreach (Node n in nodesByWeight.Values)
    {
        Console.WriteLine(n.FloatKey + " : " + n.UniqueID);
    }
}
于 2015-02-20T02:24:30.217 に答える