Sorting a time intervals

后端 未结 5 874
逝去的感伤
逝去的感伤 2021-01-27 12:25

I am giving a time interval in the form of two arrays.

A[0]=  2  B[0]=3
A[1]=  9  B[1]=11
A[2] = 5 B[2]=6
A[3] = 3 B[3]=10

I want to sort the i

5条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-27 13:11

    The classical Javanese "object oriented" approach for this is to use a dedicated class storing a pair of values (int values, in this case), and sort them, as already pointed out in most of the other answers. However, I'd recommend to not make this class Comparable. Instead, a Comparator could be used, which would make it much easier to introduce new sorting orders. Particularly, there could be Comparator implementations for sorting in ascending/descending order, based on the first/second value, respectively. Only then, object orientation plays out its advantages, compensating the "disadvantage" of having to create such a pair of int values as a "dummy data structure" in the first place...

    However, I wanted to try to find a solution for the original question as well, namely, sorting two arrays "in sync". Despite the task of sorting seemingly being trivial, one can dedicate a lot of work to doing it right (see Chapter 3 of TAOCP). A bubble sort is simple but inefficient even for medium-sized arrays. Implementing a quick- or merge sort can be fiddly when trying to get the indices right. However, one solution can be obtained by simply taking the existing sort method from java.lang.Arrays, and factoring out the most elementary building block: The swap function:

    public class ArraySort
    {
        public static void main(String[] args)
        {
            final int A[] = new int[4];
            final int B[] = new int[4];
            A[0] = 2;  B[0] = 3;
            A[1] = 9;  B[1] = 11;
            A[2] = 5;  B[2] = 6;
            A[3] = 3;  B[3] = 10;
    
            Swapper swapper = new Swapper()
            {
                @Override
                public void swap(int array[], int i0, int i1)
                {
                    ArraySort.swap(A, i0, i1);
                    ArraySort.swap(B, i0, i1);
                }
            };
            sort(A, 0, A.length, swapper);
    
            for (int i=0; i off && x[j - 1] > x[j]; j--)
                    {
                        swapper.swap(x, j, j - 1);
                    }
                }
                return;
            }
    
            int m = off + (len >> 1);
            if (len > 7)
            {
                int l = off;
                int n = off + len - 1;
                if (len > 40)
                { 
                    int s = len / 8;
                    l = med3(x, l, l + s, l + 2 * s);
                    m = med3(x, m - s, m, m + s);
                    n = med3(x, n - 2 * s, n - s, n);
                }
                m = med3(x, l, m, n);
            }
            int v = x[m];
    
            int a = off, b = a, c = off + len - 1, d = c;
            while (true)
            {
                while (b <= c && x[b] <= v)
                {
                    if (x[b] == v)
                    {
                        swapper.swap(x, a++, b);
                    }
                    b++;
                }
                while (c >= b && x[c] >= v)
                {
                    if (x[c] == v)
                    {
                        swapper.swap(x, c, d--);
                    }
                    c--;
                }
                if (b > c)
                {
                    break;
                }
                swapper.swap(x, b++, c--);
            }
    
            int s, n = off + len;
            s = Math.min(a - off, b - a);
            vecswap(x, off, b - s, s, swapper);
            s = Math.min(d - c, n - d - 1);
            vecswap(x, b, n - s, s, swapper);
    
            if ((s = b - a) > 1)
            {
                sort(x, off, s, swapper);
            }
            if ((s = d - c) > 1)
            {
                sort(x, n - s, s, swapper);
            }
        }
    
        private static void vecswap(int x[], int a, int b, int n, Swapper swapper)
        {
            for (int i = 0; i < n; i++, a++, b++)
            {
                swapper.swap(x, a, b);
            }
        }
    
        private static int med3(int x[], int a, int b, int c)
        {
            return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a)
                : (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
        }
    
    }
    

    Notes

    This is not a solution that I would recommend. It's just an attempt to answer the question

    or it can be done straight. [sic!]

    And the answer is: Yes, it is possible, although the solutions that are introducing some sort of an IntPair are more idiomatic.

    Apart from that, it would probably be more efficient to "inline" the Swapper#swap calls to directly swap elements of two arrays that are stored in instance variables, or passed as method parameters. However, I liked the genericity of such a Swapper interface. Additionally, it would be nice to generalize this even further, by passing in something like a

    interface IntArrayEntryComparator {
        int compare(int array[], int i0, int i1);
    }
    

    But the latter would go beyond what I wanted to test/demonstrate with this class.

提交回复
热议问题