Adjacent number algorithm grouper

前端 未结 13 1745
不思量自难忘°
不思量自难忘° 2021-02-15 06:55

By which I mean this:

Given the input set of numbers:

1,2,3,4,5 becomes \"1-5\".

1,2,3,5,7,9,10,11,12,14 becomes \"1-3, 5, 7, 9-12, 14\"

This is

13条回答
  •  囚心锁ツ
    2021-02-15 07:37

    As I wrote in comment, I am not fan of the use of value 0 as flag, making firstNumber both a value and a flag.

    I did a quick implementation of the algorithm in Java, boldly skipping the validity tests you already correctly covered...

    public class IntListToRanges
    {
        // Assumes all numbers are above 0
        public static String[] MakeRanges(int[] numbers)
        {
            ArrayList ranges = new ArrayList();
    
            Arrays.sort(numbers);
            int rangeStart = 0;
            boolean bInRange = false;
            for (int i = 1; i <= numbers.length; i++)
            {
                if (i < numbers.length && numbers[i] - numbers[i - 1] == 1)
                {
                    if (!bInRange)
                    {
                        rangeStart = numbers[i - 1];
                        bInRange = true;
                    }
                }
                else
                {
                    if (bInRange)
                    {
                        ranges.add(rangeStart + "-" + numbers[i - 1]);
                        bInRange = false;
                    }
                    else
                    {
                        ranges.add(String.valueOf(numbers[i - 1]));
                    }
                }
            }
            return ranges.toArray(new String[ranges.size()]);
        }
    
        public static void ShowRanges(String[] ranges)
        {
            for (String range : ranges)
            {
                System.out.print(range + ","); // Inelegant but quickly coded...
            }
            System.out.println();
        }
    
        /**
         * @param args
         */
        public static void main(String[] args)
        {
            int[] an1 = { 1,2,3,5,7,9,10,11,12,14,15,16,22,23,27 };
            int[] an2 = { 1,2 };
            int[] an3 = { 1,3,5,7,8,9,11,12,13,14,15 };
            ShowRanges(MakeRanges(an1));
            ShowRanges(MakeRanges(an2));
            ShowRanges(MakeRanges(an3));
            int L = 100;
            int[] anr = new int[L];
            for (int i = 0, c = 1; i < L; i++)
            {
                int incr = Math.random() > 0.2 ? 1 : (int) Math.random() * 3 + 2;
                c += incr;
                anr[i] = c;
            }
            ShowRanges(MakeRanges(anr));
        }
    }
    

    I won't say it is more elegant/efficient than your algorithm, of course... Just something different.

    Note that 1,5,6,9 can be written either 1,5-6,9 or 1,5,6,9, not sure what is better (if any).

    I remember having done something similar (in C) to group message numbers to Imap ranges, as it is more efficient. A useful algorithm.

提交回复
热议问题