В C# сортировка массива по возрастанию и убыванию
У меня возникли проблемы с написанием метода, который возвращает true, если элементы массива (числа) находятся в отсортированном порядке, по возрастанию или убыванию, и false, если они не находятся в любом отсортированном порядке. Я могу вернуть правильное логическое значение, если массив по возрастанию, но я не знаю, как проверить порядок убывания в том же методе. В настоящее время у меня:
public static bool IsArraySorted(int[] numbers)
{
for (int i = 1; i < numbers.Length; i++)
{
if (numbers[i - 1] > numbers[i])
return false;
}
return true;
}
кто-нибудь может предложить помощь о том, как проверить сортированный нисходящий массив? Ура!
5 ответов
это должно быть что-то вроде:
public static bool IsArraySorted(int[] numbers)
{
bool? ascending = null;
for (int i = 1; i < numbers.Length; i++)
{
if (numbers[i - 1] != numbers[i])
{
bool ascending2 = numbers[i - 1] < numbers[i];
if (ascending == null)
{
ascending = ascending2;
}
else if (ascending.Value != ascending2)
{
return false;
}
}
}
return true;
}
обратите внимание на использование ascending
переменная для сохранения" направления " массива. Он инициализируется при первом обнаружении двух различных элементов.
обратите внимание, что если вы хотите, вы даже можете вернуть "направление" массива:
public static bool IsArraySorted(int[] numbers, out bool isAscending)
{
isAscending = true;
bool? ascending = null;
и внутри if (ascending == null)
if (ascending == null)
{
ascending = ascending2;
isAscending = ascending2;
}
это общая версия, основанная на IEnumerable<TSource>
:
public static bool IsSorted<TSource>(IEnumerable<TSource> source, out bool isAscending, Comparer<TSource> comparer = null)
{
isAscending = true;
if (comparer == null)
{
comparer = Comparer<TSource>.Default;
}
bool first = true;
TSource previous = default(TSource);
bool? ascending = null;
foreach (TSource current in source)
{
if (!first)
{
int cmp = comparer.Compare(previous, current);
if (cmp != 0)
{
bool ascending2 = cmp < 0;
if (ascending == null)
{
ascending = ascending2;
isAscending = ascending2;
}
else if (ascending.Value != ascending2)
{
return false;
}
}
}
first = false;
previous = current;
}
return true;
}
обратите внимание на использование bool first
/TSource previous
обработки i - 1
(и тот факт, что for
цикл смог "пропустить" первый элемент)
Использование Linq -
public static bool IsArraySorted(int[] numbers)
{
var orderedAsc = numbers.OrderBy(a => a);
var orderedDes = numbers.OrderByDescending(a => a);
bool isSorted = numbers.SequenceEqual(orderedAsc) ||
numbers.SequenceEqual(orderedDes);
return isSorted;
}
Это использует один цикл для тестирования обоих случаев:
public static bool IsSorted<T>(IEnumerable<T> items, Comparer<T> comparer = null)
{
if (items == null) throw new ArgumentNullException("items");
if (!items.Skip(1).Any()) return true; // only one item
if (comparer == null) comparer = Comparer<T>.Default;
bool ascendingOrder = true; bool descendingOrder = true;
T last = items.First();
foreach (T current in items.Skip(1))
{
int diff = comparer.Compare(last, current);
if (diff > 0)
{
ascendingOrder = false;
}
if (diff < 0)
{
descendingOrder = false;
}
last = current;
if(!ascendingOrder && !descendingOrder) return false;
}
return (ascendingOrder || descendingOrder);
}
использование:
int[] ints = { 1, 2, 3, 4, 5, 6 };
bool isOrderedAsc = IsSorted(ints); // true
bool isOrderedDesc = IsSorted(ints.Reverse()); //true
Если вы сделаете его методом расширения, вы можете использовать его с любым типом:
bool ordered = new[]{"A", "B", "C"}.IsSorted();
public static boolean checkSortedness(final int[] data)
{
for (int i = 1; i < data.length; i++)
{
if (data[i-1] > data[i]) {
return false;
}
}
return true;
}
где мой ответ? Я написал его около часа назад:
public enum SortType
{
unsorted = 0,
ascending = 1,
descending = 2
}
public static SortType IsArraySorted(int[] numbers)
{
bool ascSorted = true;
bool descSorted = true;
List<int> asc = new List<int>(numbers);
asc.Sort();
for (int i = 0; i < asc.Count; i++)
{
if (numbers[i] != asc[i]) ascSorted = false;
if (numbers[asc.Count - 1 - i] != asc[i]) descSorted = false;
}
return ascSorted ? SortType.ascending : (descSorted? SortType.descending : SortType.unsorted);
}
пример: