Ответ 1
if (ar.SequenceEqual(ar.OrderBy(x => x)))
{
if (ar.Distinct().Count() == ar.Length)
return 1;
else
return 2;
}
else
{
return 0;
}
Я читаю книгу С# для новичков, и на каждом конце главы есть упражнения, на которые нужно ответить, основываясь на проведенных уроках.
Одно из этих упражнений идет следующим образом: (не точные формулировки)
Напишите программу, которая будет принимать int как длину массива, и значения для массива.
Затем напечатает:
" 0", если массив не отсортирован по возрастанию.
" 1", если он отсортирован. И,
" 2", если он отсортирован, но есть дубликаты.
Пример:
// 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? Как?
if (ar.SequenceEqual(ar.OrderBy(x => x)))
{
if (ar.Distinct().Count() == ar.Length)
return 1;
else
return 2;
}
else
{
return 0;
}
Чистая альтернатива 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))));
В качестве примечания ваша выраженная логика не 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;
}
В этом методе мы рано возвращаемся, как только у нас есть элемент, меньший, чем предыдущий элемент. В противном случае мы будем устанавливать логическое значение, если встретим соответствующее значение. В конце цикла мы знаем, что массив отсортирован по возрастанию. Осталось только проверить, было ли совпадение.
Непроверенные.
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;