C# sorting arrays in ascending and descending order

前端 未结 7 1055
感动是毒
感动是毒 2020-12-19 02:27

I\'m having trouble writing a method that returns true if the elements of an array (numbers) are in sorted order, ascending or descending, and false, if they are not in any

相关标签:
7条回答
  • 2020-12-19 02:59

    Using 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;
    }
    
    0 讨论(0)
  • 2020-12-19 03:09

    It should be something like:

    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;
    }
    

    Note the use of the ascending variable to save the "direction" of the array. It is initialized the first time two elements that are different are found.

    Note that if you want, you can even return the "direction" of the array:

    public static bool IsArraySorted(int[] numbers, out bool isAscending)
    {
        isAscending = true;
        bool? ascending = null;
    

    and inside the if (ascending == null)

    if (ascending == null)
    {
        ascending = ascending2;
        isAscending = ascending2;
    }
    

    This is a generic version based on 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;
    }
    

    Note the use of bool first/TSource previous to handle the i - 1 (and the fact that the for cycle was able to "skip" the first element)

    0 讨论(0)
  • 2020-12-19 03:12

    It looks more like an academic assignment than a practical question. I guess it does not hurt to return to basics once in a while:

    public static bool IsSortedAscOrDesc(int[] arr)
    {
        int last = arr.Length - 1;
        if (last < 1) return true;
    
        bool isSortedAsc = true;
        bool isSortedDesc = true;
    
        int i = 0;
        while (i < last && (isSortedAsc || isSortedDesc)) 
        {
            isSortedAsc &= (arr[i] <= arr[i + 1]);
            isSortedDesc &= (arr[i] >= arr[i + 1]);
            i++;
        }
    
        return isSortedAsc || isSortedDesc;
    }
    
    0 讨论(0)
  • 2020-12-19 03:17
    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;
    }
    
    0 讨论(0)
  • 2020-12-19 03:19

    Where is my answer? I wrote it about an hour ago:

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

    Example:

    enter image description here

    0 讨论(0)
  • 2020-12-19 03:21

    An array with 2 (or less) elements is sorted,
    {0,0} is sorted asc & desc, {0,1} asc, {1,0} desc, {1,1} asc & desc.
    It is possible to use one loop, but it seems faster to separate cases. For an array with more than 2 elements,
    if the first element is less than the last element, check: a[i] <= a[i + 1].
    Below I use "ai <= (ai = a[i])", compare the old value of ai with the new value of ai, each element is read once.

    using System;
    class Program
    {
        static void Main()
        {
            int i = 512; int[] a = new int[i--]; while (i > 0) a[i] = i--; //a[511] = 1;
            Console.WriteLine(isSorted0(a));
            var w = System.Diagnostics.Stopwatch.StartNew();
            for (i = 1000000; i > 0; i--) isSorted0(a);
            Console.Write(w.ElapsedMilliseconds); Console.Read();
        }
    
        static bool isSorted0(int[] a)  // 267 ms
        {
            if (a.Length < 3) return true; int j = a.Length - 1;
            return a[0] < a[j] ? incr(a) : a[0] > a[j] ? decr(a) : same(a);
        }
        static bool incr(int[] a)
        {
            int ai = a[0], i = 1, j = a.Length;
            while (i < j && ai <= (ai = a[i])) i++; return i == j;
        }
        static bool decr(int[] a)
        {
            int ai = a[0], i = 1, j = a.Length;
            while (i < j && ai >= (ai = a[i])) i++; return i == j;
        }
        static bool same(int[] a)
        {
            int ai = a[0], i = 1, j = a.Length - 1;
            while (i < j && ai == a[i]) i++; return i == j;
        }
    
        static bool isSorted1(int[] numbers)  // 912 ms  accepted answer
        {
            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;
        }
    }
    

    A short version.

        static bool isSorted(int[] a)
        {
            if (a.Length < 3) return true; int i = a.Length - 1, ai = a[i--];
            if (ai > a[0]) while (i >= 0 && ai >= (ai = a[i])) i--;
            else if (ai < a[0]) while (i >= 0 && ai <= (ai = a[i])) i--;
            else while (i >= 0 && ai == a[i]) i--; return i < 0;
        }
    
    0 讨论(0)
提交回复
热议问题