How would you display an array of integers as a set of ranges? (algorithm)

后端 未结 16 2898
我在风中等你
我在风中等你 2021-02-15 18:04

Given an array of integers, what is the simplest way to iterate over it and figure out all the ranges it covers? for example, for an array such as:

$numbers = ar         


        
16条回答
  •  抹茶落季
    2021-02-15 18:26

    Here's a C# 3.0'y way of doing it:

    Points of interest:

    • automatic properties (public int Property { get; set; })
    • using new object initializers (new Range { Begin = xxx; ... }
    • using yield for lazy evaluation
    • using linq extension methods (First() and Skip())

    -

    class Demo
    {
        private class Range
        {
            public int Begin { get; set; }
            public int End { get; set; }
    
            public override string ToString()
            {
                if (Begin == End)
                    return string.Format("{0}", Begin);
                else
                    return string.Format("{0}-{1}", Begin, End);
            }
        }
    
        static void Main(string[] args)
        {
            var list = new List { 1, 3, 4, 5, 6, 8, 11, 12, 14, 15, 16 };
            // list.Sort();
            var ranges = GetRangesForSortedList(list);
    
            PrintRange(ranges);
    
            Console.Read();
        }
    
        private static void PrintRange(IEnumerable ranges)
        {
            if (ranges.Count() == 0)
                return;
    
            Console.Write("[{0}", ranges.First());
    
            foreach (Range range in ranges.Skip(1))
            {
                Console.Write(", {0}", range);
            }
    
            Console.WriteLine("]");
        }
    
        private static IEnumerable GetRangesForSortedList(IList sortedList)
        {
            if (sortedList.Count < 1) 
                yield break;
    
            int firstItem = sortedList.First();
            Range currentRange = new Range { Begin = firstItem, End = firstItem };
    
            foreach (int item in sortedList.Skip(1))
            {
                if (item == currentRange.End + 1)
                {
                    currentRange.End = item;
                }
                else
                {
                    yield return currentRange;
                    currentRange = new Range { Begin = item, End = item };
                }
            }
    
            yield return currentRange;
        }
    }
    

    Cheers, David

提交回复
热议问题