2

このような拡張メソッドを作成したい

public static bool AllConsecutives(this IEnumerable<int> intValues )

リスト内のすべての項目が連続している(ギャップがない)場合、このメソッドはtrueを返す必要があります

いくつかのテストケース

(new List<int>() {2, 3, 4, 5, 6}).AllConsecutives() == true
(new List<int>() {3, 7, 4, 5, 6}).AllConsecutives() == true //as it is not sensitive to list order
(new List<int>() {2, 3, 4, 7, 6}).AllConsecutives() == false //as the five is missing
4

7 に答える 7

4
int expected = intValues.Min();
foreach(int actual in intValues.OrderBy(x => x))
{
    if (actual != expected++)
       return false;
}

return true;

を実行する前に、コレクションに少なくとも1つのアイテムがあることを確認することもできますMin。または、分を取る前にアイテムを並べ替えることができます(この場合、最初のアイテムになるか、コレクションが空の場合は何もなりません)。また、この場合、最小値を見つけるために1回の反復を保存します。

var sortedValues = intValues.OrderBy(x => x);
int expected = sortedValues.FirstOrDefault();

foreach (int actual in sortedValues)
{
    if (actual != expected++)
        return false;
}

return true;
于 2012-06-12T13:15:34.420 に答える
2

重複と最大値の差が含まれていない場合、リストは連続しています。そして最小値。値は、リスト内のアイテムの数から1を引いたものに等しいため、次のようになります。

public static bool AllConsecutives(this IEnumerable<int> intValues) 
{
   int minValue = Int32.MaxValue;
   int maxValue = Int32.MinValue;
   int count = 0;
   HashSet<int> values = new HashSet<int>();
   foreach (int intValue in intValues) {
     if (values.Contains(intValue))         
       return false;
     values.Add(intValue);
     if (intValue > maxValue)
       maxValue = intValue;
     if (intValue < minValue)
       minValue = intValue;
     count++;
   }
   return (count == 0) || (maxValue-minValue+1 == count);
}
于 2012-06-12T13:22:05.867 に答える
2

試してみて、与えられた例で動作するようです

public static bool AllConsecutives(this IEnumerable<int> intValues ) 
{
    var ord = intValues.OrderBy(i => i);
    int curV = ord.Min();
    foreach(int x in ord)
    {
        if(x != curV)
           return false;
        curV++;
    }
    return true;
}
于 2012-06-12T13:22:48.440 に答える
1

このようなもの:

if (intValues.Count() <= 1)
                return true;

var ordered = intValues.OrderBy(i => i).ToList();

return (ordered.First() + ordered.Count() - 1) == ordered.Last();
于 2012-06-12T13:16:38.677 に答える
1

Linqのチェックと使用中にエラーが発生しました:

 public static class myExtension
{

   public static bool AllConsecutives(this IEnumerable<int> targetList)
   {
      bool result = false;

      if ((targetList != null) && (targetList.Any ()))
      {
         var ordered = targetList.OrderBy (l => l);

         int first = ordered.First ();

         result = ordered.All (item => item == first++);

      }

      return result;

   }

}

// tested with

void Main()
{
 Console.WriteLine ( (new List<int>() {2, 3, 4, 5, 6}).AllConsecutives() ); // true
 Console.WriteLine ( (new List<int>() {3, 7, 4, 5, 6}).AllConsecutives() ); // true //as it is not sensitive to list order
 Console.WriteLine ( (new List<int>() {2, 3, 4, 7, 6}).AllConsecutives() ); // false //as the five is missing
}
于 2012-06-12T13:27:45.423 に答える
0

並べ替えを必要としない別の可能な解決策は、ハッシュセットを使用することです。ハッシュセットを構築するときに、最小値を保持できます。これにより、実行時間はO(n)になります。これは重複する値を処理しません。ハッシュセットの構築中にチェックを追加して、ハッシュセットにすでに値が含まれているかどうかを確認できます。

HashSet<int> hash = new HashSet<int>();
int minValue = int.MaxValue;
foreach(int i in list)
{
    if(minValue > i)
        minValue = i;
        hash.Add(i);
}

for(int count = 1; count < list.Count; ++count)
{
    if(!hash.Contains(++minValue))
        return false;

}
return true;
于 2012-06-12T15:06:12.103 に答える
0
list.Sort();
return !list.Skip(1).Where((i, j) => (i != (list[j] + 1))).Any();
于 2012-06-12T13:38:37.440 に答える