0

私はリストのリストを持っています。各内部リストは次のような整数のリストです(コードはわかりやすくするために簡略化されています)。

var listOfLists = new List<List<int>>
{
     new List<int> {6, 0, 2, 5, 6},      // #3 in sort order
     new List<int> {6, 0, 2, 2, 5, 6},   // #2 in sort order
     new List<int> {0, -1, 0, 0, 7},     // #1 in sort order
     new List<int> {11, 3, 5, 5, 12},    // #4 in sort order
};

次のルールに従って、LINQ-to-Objectsを使用してこれらのリストを並べ替えたいと思います。

  1. いずれかのリストが空の場合、空でないリストが最初にソートされます
  2. 最小数が最も少ないリストが最初にソートされます
  3. 同点の場合、最小の重複の最大数が最初にソートされます。例:の{2,2}前に並べ替え{2}ます。
  4. それでも同点の場合は、両方のリストから最小値を削除して、ステップ1に進みます。

バックグラウンド:

各リストは、それぞれ1つ以上の小売店がある場所を表しています。各小売店には、その場所の補充がどれほどひどく必要かを定義する「緊急」番号が割り当てられています。「最悪」は-1です。これは通常、顧客が空の製品について不満を言っていることを意味します。0は通常、ストアで売れ筋商品が不足していることを意味します。1は通常、ほとんど空の店舗です。等々。実際には、緊急度の計算は複雑で、データマイニングによって検証された複数の基準に基づいていますが、数値を取得する方法は並べ替えにとって重要ではありません。

最も緊急性の高い場所を見つけたいと思います。これは、最も緊急性の高い店舗がある場所として定義し、その緊急度のレベルの店舗の数をタイブレーカーとして使用します。

4

2 に答える 2

1

私は問題を2つに分けました:

最初に、問題の重複部分によるタイブレークに対処するために、重複ごとに小さな浮動小数点数(.0000001など)を減算しました。たとえば、次のようになります。

from m in list
group m by m.Urgency into g
orderby g.Key
select g.Key - (g.Count()-1) *.0000001

これにより、はるかに単純な問題が発生しました。2つのシーケンスをアイテムごとに比較するだけです。

このタスクのために、私はJon Skeetの答えを(それらの要素によって)IEnumerableを比較するための組み込みの方法はありますか?。コードのバグを修正するために彼の比較プログラムを変更する必要がありました。また、並べ替えルールで長いシーケンスが短いシーケンスの前に並べ替えられたものとして扱われたためですが、それ以外の場合はコードをそのままコピーしました。

結果のソリューションは次のとおりです。ここに投稿するためにいくらか簡略化されています。

var urgentLocations = 
               (   from m in Stores
                   group m by m.Location into g
                   where g.Min(m => m.Urgency) < 14
                   select new {Name = g.Key, Stores = g.OrderBy(m=>m.Urgency).ToList()})
               .OrderBy (g=>g.Stores, new LocationComparer())
               .ToList();


public class LocationComparer : IComparer<List<Machine>>
{

    public int Compare(List<Store> source1, List<Store> source2)
    {
        var reduced1 = from m in source1
                        group m by m.Urgency into g
                        orderby g.Key
                        select g.Key - (g.Count() - 1) * .0000001;
        var reduced2 = from m in source2
                        group m by m.Urgency into g
                        orderby g.Key
                        select g.Key - (g.Count() - 1) * .0000001;
        return SequenceCompare(reduced1, reduced2);
    }

    // adapted from https://stackoverflow.com/a/2811805/126352 but modified so that 
    // shorter sequences are sorted last
    public int SequenceCompare<T>(IEnumerable<T> source1, IEnumerable<T> source2)
    {
        // You could add an overload with this as a parameter 
        IComparer<T> elementComparer = Comparer<T>.Default;
        using (IEnumerator<T> iterator1 = source1.GetEnumerator())
        using (IEnumerator<T> iterator2 = source2.GetEnumerator())
        {
            while (true)
            {
                bool next1 = iterator1.MoveNext();
                bool next2 = iterator2.MoveNext();
                if (!next1 && !next2) // Both sequences finished 
                {
                    return 0;
                }
                if (!next1) // Only the first sequence has finished
                {
                    return 1;
                }
                if (!next2) // Only the second sequence has finished 
                {
                    return -1;
                }
                // Both are still going, compare current elements 
                int comparison = elementComparer.Compare(iterator1.Current,
                                                 iterator2.Current);
                // If elements are non-equal, we're done 
                if (comparison != 0)
                {
                    return comparison;
                }
            }
        }
    }
}
于 2012-09-14T23:09:42.553 に答える
0

これは にも当てはまりCompareますよね?

public int Compare(List<Store> source1, List<Store> source2)
{        
    var reduced1 = source1.Select(s => s.Urgency).OrderBy(u => u);
    var reduced2 = source2.Select(s => s.Urgency).OrderBy(u => u);
    return SequenceCompare(reduced1, reduced2);
}
于 2012-09-16T01:24:36.177 に答える