2012-06-12 2 views
2

Я хочу создать метод расширения, как этотAllConsecutives в Списке <int>

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

Этот метод возвращает истину, если все элементы в списке подряд (без пробелов)

несколько тестов

(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 
+0

Да, и? вы что-то пробовали? – MBen

+0

Я пробовал с агрегатной функцией, но не мог понять, что такое семя и аккумулятор. –

+0

Агрегат будет работать только для упорядоченного списка, imo, так как вы всегда посещаете два последовательных элемента. – phg

ответ

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

return true; 

Вы также можете проверить, что коллекция имеет по крайней мере один пункт, б до выполнения Min. Или вы можете сортировать элементы до приема min (в этом случае он будет первым, или не будет, если коллекция пуста). Кроме того, в этом случае вы сэкономите одну итерацию для нахождения минимального значения:

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

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

return true; 
+0

Не работает с вторым примером OP. – ken2k

+0

Он хотел, чтобы он не зависел от порядка. Может быть, есть что-то быстрее, чем сначала сортировать его, а чем применить к вам алго? – phg

+0

Извините, не заметил, что это должно быть не зависящим от заказа –

1

Что-то вроде этого:

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

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

return (ordered.First() + ordered.Count() - 1) == ordered.Last(); 
+0

'{2, 3, 4, 7, 6}' передает это. – Rawling

+0

Да, только что пришло в голову, как caffiene hit ... – Paddy

+0

Почему вы сортируете три раза? –

2

Список последователен, если он не содержит дубликатов и разность между макс. и мин. значения равно количеству элементов в списке минус один, так:

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); 
} 
+0

Я что-то пропустил или «значения» всегда пустые? – phg

+0

@png: whops ... спасибо, исправлено – MiMo

+0

+1 для решения O (n), без сортировки. –

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; 
} 
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 
} 
0
list.Sort(); 
return !list.Skip(1).Where((i, j) => (i != (list[j] + 1))).Any(); 
0

Другим возможным решением, которое не требует сортировки, является использование hashset, и при построении hashset вы можете удерживать m в цене. При этом время выполнения будет равно O (n). Это не позаботится о повторяющихся значениях, которые вы можете просто добавить проверку при построении hashset и посмотреть, не содержит ли hashset значение.

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; 
Смежные вопросы