2016-08-18 3 views
-1

私は{1,2,3,5,8,9,10}のような整数のリストを持っていますので、次の結果が必要です [1,3]、[5,5]、[8,10]与えられた整数リスト(連続したセグメント)をどのように見つけるか?

私は命令的なスタイルを使用して解決策を書いたが、私は関数型プログラミングに対応した解決策が必要だ。

マイ不可欠ソリューション:

public static List<ContinuousNotificationSegment> ConvertToNotificationSegment(this List<NotificationDTO> input) 
    { 
     var sortedNotificationList = input.Select(n => n.ID).ToList(); 
     sortedNotificationList = sortedNotificationList.OrderBy(n => n).ToList(); 
     List<ContinuousNotificationSegment> continuousSegments = new List<ContinuousNotificationSegment>(); 

     long continuousSegmentStart = 0, continuousSegmentEnd = 0; 

     for (int i = 0; i < sortedNotificationList.Count; i++) 
     {     
      if (IsContinuous(sortedNotificationList[i], ((i + 1) < sortedNotificationList.Count ? sortedNotificationList[i + 1] : -999))) 
      { 
       continuousSegmentStart = continuousSegmentStart == 0 ? sortedNotificationList[i] : continuousSegmentStart; 
      } 
      else 
      { 
       continuousSegmentEnd = sortedNotificationList[i]; 

       continuousSegments.Add(new ContinuousNotificationSegment 
       { 
        MinNotificationId = continuousSegmentStart == 0 ? continuousSegmentEnd : continuousSegmentStart, 
        MaxNotificationId = continuousSegmentEnd 
       }); 

       continuousSegmentStart = 0; 
      } 
     } 

     return continuousSegments; 
    } 

    private static bool IsContinuous(long prevValue, long nextValue) 
    { 
     return nextValue - prevValue == 1; 
    } 
+2

です'{1,2,3,5,8,9,10} 'を結果[1,3]、[5,5]、[8,10]'に変換しますか? –

+1

@DavidArno連続した数字に基づく範囲は、順序付きリストの前の数字より1つ大きくないようです。 – juharr

+0

@DavidArno連続する整数の範囲のリストです。 – Luaan

答えて

2
var input = new[] { 1, 2, 3, 5, 8, 9, 10 }; 

var result = 
    input 
     .Skip(1) 
     .Aggregate(
      input.Take(1).Select(x => new { start = x, end = x }).ToList(), 
      (a, x) => 
      { 
       var last = a.Last(); 
       if (last.end + 1 == x) 
       { 
        a[a.Count - 1] = new { start = last.start, end = x }; 
       } 
       else 
       { 
        a.Add(new { start = x, end = x }); 
       } 
       return a; 
      }); 

動作します。私が取得:

result

1

あなたは、その後数と現在数と前回との差が1より大きい場合にインクリメントされるグループIDを選択し、最初の番号のリストを注文していることを行うことができます。次に、そのグループ化IDをグループ化し、最小値と最大値を範囲として取ります。

public static IEnumerable<Tuple<int, int>> Runs(this IEnumerable<int> nums) 
{ 
    int? prev = null; 
    int group = 0; 
    return nums.OrderBy(n => n) 
     .Select(
      n => 
      { 
       if (prev.HasValue && n - prev.Value > 1) { group++; } 
       prev = n; 
       return new { group, num = n }; 
      }) 
     .GroupBy(x => x.group) 
     .Select(g => new Tuple<int, int>(g.Min(x => x.num), g.Max(x => x.num))); 
} 

このコード

var nums = new[] { 1, 2, 3, 5, 7, 8, 9 }; 
Console.WriteLine(string.Join(";", nums.Runs())); 

出力

(1,3)、(5,5)、(7,9)

0

最もコンパクト明確なLINQは私が思い付くかもしれません:

var intList = new List<int> { 1, 2, 3, 5, 8, 9, 10 }; 

var agg = intList.Aggregate(new List<List<int>> { new List<int>() }, (i, j) => 
    { 
     if (!i.Last().Any() || i.Last().Last() + 1 == j) 
      i.Last().Add(j); 
     else 
      i.Add(new List<int> { j }); 
     return i; 
    }).Select(i => new List<int> { i.First(), i.Last() }); 

結果は、質問に記載されているとおりです。

1

私は機能的に、それはのようになります。プログラムするteachedされてきたように(、それは[擬似コード]警告だ!と[末尾再帰]!)

GetRanges(input) 
    if (input == null || input.Count == 0) 
     return {}; 

    var ranges = {}; 
    GetRangesInternal(ranges, {null, null}, input); 
    return ranges; 

GetRangesInternal(ranges, {initialElement, lastElement}, input) => 
    var head = input.Take(1); 
    var tail = input.Skip(1); 

    // no first element - prepare new range and move on 
    if (initialElement == null) 
     GetRangesInternal(ranges, {head, head}, tail); 
     return; 

    // range continued - update it and move on 
    if (head == lastElement+1) 
     GetRangesInternal(ranges, {initialElement, head}, tail) 
     return; 

    // range stopped - add it to result 
    ranges.Add({initialElement, lastElement}); 
    GetRangesInternal(ranges, {head, head}, tail); 

GetRangesエントリポイントは、背後にあるルールは何

関連する問題