2010-10-21 3 views
17

Я читаю книгу C# для новичков, и на каждом конце главы есть упражнения, на которые нужно ответить, основываясь на проведенных уроках.Можно ли выразить этот код в LINQ?

Один из этих упражнений идет так: (не точные формулировки)

Напишите программу, которая будет принимать Int как длина массива, и значение для массива.
Затем напечатает:
«», если массив не отсортирован по возрастанию.
"" если отсортировано. И,
"" если сортировка, но есть дубликаты.

Пример:

// Sorted 
Input: 1, 2, 3, 5 
Print: 1 

// Not sorted 
Input: 2, 1, 3, 6 
Print: 0 

// Sorted, but with duplicates 
Input: 2, 2, 3, 7 
Print: 2 

Я не знаю, если моя логика абсолютна, но как-то работает,
, и я сделал это в моем пути, используя этот код:

int arrayLength = 0; 
int prev, next; 
int sortStatus = 1; 

Console.Write("Input array Length: "); 
arrayLength = Convert.ToInt32(Console.ReadLine()); 
int[] ar = new int[arrayLength]; 

for (int x = 0; x < arrayLength; x++) 
{ 
    Console.Write("Input {0} value: ", (x+1).ToString()); 
    ar[x] = Convert.ToInt32(Console.ReadLine()); 
} 

for (int x = 0; x < ar.Length-1; x++) 
{ 
    prev = (int)ar[x]; 
    next = (int)ar[x + 1]; 

    if (next < prev) 
     sortStatus = 0; 
    if (next == prev) 
     sortStatus = 2; 
} 

Console.Write(sortStatus.ToString()); 
Console.Read(); 

Можно ли выразить это в LINQ? Как?

+3

+1 за вопрос хорошо структурированный вопрос, а также желая знать, как улучшить то, что вы уже сделали. – RPM1984

+0

@ RPM1984: thank sir :) – yonan2236

+0

Учитывая, что фактический код, содержащий логику «isSorted», имеет длину менее 10 строк (и должен действительно быть по-своему), действительно ли вы хотите, чтобы свернутый оператор LINQ заменил его? –

ответ

17
if (ar.SequenceEqual(ar.OrderBy(x => x))) 
{ 
    if (ar.Distinct().Count() == ar.Length) 
     return 1; 
    else 
     return 2; 
} 
else 
{ 
    return 0; 
} 
+0

Спасибо, сэр, я попробую ... – yonan2236

+0

Да, это путь. Хорошая работа. +1 – RPM1984

+0

это работает сэр ... :) спасибо. – yonan2236

5

Чистый LINQ альтернатива ... (для только академический интерес (но, вероятно, еще быстрее, чем принятый ответ!)

var input = new int[] { 1, 2, 3, 4, 5 }; 

var output = input.Zip(input.Skip(1), (a, b) => new {a=a, b=b}) 
       .Aggregate(1, (status, x) => status == 0 ? 0 : ((x.a > x.b ? 0 : (x.a == x.b ? 2 : status)))); 
+0

Хм .. что такое 'input' здесь? Это мой массив? – yonan2236

+0

Да, вход будет вашим массивом. –

+0

спасибо за вашу версию ответа :) – yonan2236

3

Как примечание, сцеженным без LINQ логика имеет недостаток .

if (next < prev) 
    sortStatus = 0; 
if (next == prev) 
    sortStatus = 2; 

Ваше правило говорит о том, что массив должен быть отсортирован в порядке возрастания, но есть дубликаты, чтобы получить выход 2. Тем не менее, ваша логика будет возвращать 2 для { 1, 9, 7, 7 }.

Другим способом написания кода может быть следующее. (Это не с помощью LINQ, но это слишком долго, чтобы получить возможность отправлять как комментарий к вашему вопросу.)

static int EvaluateArray(int[] array) 
{ 
    int? lastItem = null; 
    bool match = false; 
    foreach (int item in array) 
    { 
     if (item < lastItem) 
      return 0; 
     else if (item == lastItem) 
      match = true; 

     lastItem = item; 
    } 

    if (match) 
     return 2; 

    return 1; 
} 

В этом методе мы рано возвращаться, как только у нас есть пункт меньше, чем в предыдущем пункте , В противном случае мы будем устанавливать логическое значение, если встретим соответствующее значение. В конце цикла мы знаем, что массив отсортирован по возрастанию. Осталось только проверить, был ли матч.

+0

Спасибо, что вызвали мою ошибку. Я буду учиться на этом. – yonan2236

+0

Сэр просто вопрос, в вашем коде выше, что означает этот фрагмент кода? 'Int? lastItem = null; '. Вещь ''? "' There there ... – yonan2236

+2

@yonan: Это сокращенно для 'Nullable '. В C# 2 была введена концепция типов значений NULL. Обычным типам значений, таким как 'int', не может быть присвоено значение null, что привело к тому, что разработчики, использующие« магические »значения, часто означали« no value ». (Рассмотрим 'string.IndexOf (substring)' возвращает -1, если подстрока не найдена в строке.) С 'Nullable ', теперь у нас есть способ фактически указать, что что-то не имеет значения. В C# мы можем выразить это с сокращением. 'int?' является сокращением для 'Nullable ' очень похоже на 'int' на самом деле является сокращением C# для' Int32'. –

0

Непрошеным.

IEnumerable<int> signs = 
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]); 

int result = 
    signs.Any(sign => sign < 0) ? 0 : 
    signs.All(sign => 0 < sign) ? 1 : 
    2; 

Также непроверенных:

int minSign = !ar.Skip(1).Any() ? 1 : 
(
    from i in Enumerable.Range(0, ar.Length).Skip(1) 
    select ar[i-1].CompareTo(ar[i]) 
).TakeWhile(x => 0 <= x).Min(); 

int result = 
    minSign < 0 ? 0 : 
    0 < minSign ? 1 : 
    2; 
+0

Прошу простить мое искусство ascii ... на самом деле, дайте мне знать, если этот бит запутан - (x => 0 <= x) –

+0

спасибо за ответ :) – yonan2236

Смежные вопросы