Sorting a time intervals

后端 未结 5 867
逝去的感伤
逝去的感伤 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 12:54

    instead having two arrays, create object which holds your intervals

    class Interval  implements Comparable<Interval>  {
    
    private Long start,completed
    
     public Interval(Long start, Long completed) {
            this.start = start;
            this.completed = completed;
    }
    
    
      @Override
      public int compareTo(Interval o) {
        return start.compareTo(o.start);
      }
    
    //getters and setters ommited
    }
    

    then, all what you need to do is implement compareTo method and put all your data in some collection ie List<Interval> intervals

    and used Collections.sort(intervals) to sort them

    EDIT

    Example:

    originally you have:

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

    lets replace this by:

    List<Interval> intervals = new ArrayList<>();
    intervals.add(new Interval(2L,3L));
    intervals.add(new Interval(9L,11L));
    intervals.add(new Interval(5L,6L));
    intervals.add(new Interval(3L,10L));
    //NOTE L is added at the end variable as interval uses Long, if you change it to integer you dont need to add it;
    

    And now all what you need to do is sort

    Collection.sort(intervals);
    
    0 讨论(0)
  • 2021-01-27 12:58

    Try:

    private static class StartEnd implements Comparable<StartEnd> {
        private final int start;
        private final int end;
        // + constructor + getters
        @Override
        public int compareTo(StartEnd other) {
            return start - other.getStart();
        }
    }
    
    public void sort(int[] starts, int[] ends) {
        StartEnd[] ses = new StartEnd[starts.length];
        for(int i = 0 ; i < starts.length ; ++i) {
            ses[i] = new StartEnd(starts[i], ends[i]);
        }
        Arrays.sort(sis);
        // re-insert
        for(int i = 0 ; i < ses.length ; ++i) {
            starts[i] = ses[i].getStart;
            ends[i] = ses[i].getEnd();
        }
    }
    
    0 讨论(0)
  • 2021-01-27 13:02

    Step 1: Java is an object oriented language; learn to use objects.

    Possible class for the time interval

    public class TimeInterval implements Comparable<TimeInterval>
    {
        private int end;
        private int start;
    
        public TimeInterval(
            final int end,
            final int start)
        {
            this.end = end;
            this.start = start;
        }
    
        public int getEnd()
        {
            return end;
        }
    
        public int getStart()
        {
            return start;
        }
    
        public int comareTo(final TimeInterval other)
        {
            if (other == null)
            {
                return -1; // this will put the null value objects at the end.
            }
    
            return start - other.start;
        }
    }
    
    0 讨论(0)
  • 2021-01-27 13:03

    It can be done straight, since you dont show what have you tried so far I just give you the algorithm:

    for j = 1 to n
        for i = i+1 to n
            if(A[i]>A[j]){
                swap(A[i],A[j])
                swap(B[i],B[j])
            }
    

    you can easily convert it to java code.

    this algorithm is buble sort if you want better algorithm use this wiki link to improve your time.

    As DwB want here is merge sort full java code that do what you want. I got merge sort algorithm from here and modify to satisfy your need. also you could see the working version on Ideone

    Merge Sort:

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class Ideone
    {
        private int[] A;
        private int[] B;
        private int[] helperA;
        private int[] helperB;
    
        private int length;
    
        public static void main (String[] args){
            int[] As = {2,9,5,3};
            int[] Bs = {3,11,6,10};
            new Ideone().sort(As,Bs);
        }
    
        public void sort(int[] As , int[] Bs) {
            A = As;
            B = Bs;
            length = A.length;
            this.helperA = new int[length];
            this.helperB = new int[length];
            mergesort(0, length - 1);
            for(int i = 0 ; i<length ; i++)
            System.out.println("(" + A[i] + "," + B[i]+  ")");
        }
    
        private void mergesort(int low, int high) {
            // check if low issmaller then high, if not then the array is sorted
            if (low < high) {
            // Get the index of the element which is in the middle
            int middle = low + (high - low) / 2;
            // Sort the left side of the array
            mergesort(low, middle);
            // Sort the right side of the array
            mergesort(middle + 1, high);
            // Combine them both
            merge(low, middle, high);
            }
        }
    
        private void merge(int low, int middle, int high) {
    
            // Copy both parts into the helper array
            for (int i = low; i <= high; i++) {
                helperA[i] = A[i];
                helperB[i] = B[i];
            }
    
            int i = low;
            int j = middle + 1;
            int k = low;
            // Copy the smallest values from either the left or the right side back
            // to the original array
            while (i <= middle && j <= high) {
                if (helperA[i] <= helperA[j]) {
                    A[k] = helperA[i];
                    B[k] = helperB[i];
                    i++;
                } else {
                    A[k] = helperA[j];
                    B[k] = helperB[j];
                    j++;
                }
                k++;
            }
            // Copy the rest of the left side of the array into the target array
            while (i <= middle) {
                A[k] = helperA[i];
                B[k] = helperB[i];
                k++;
                i++;
            }
        }
    }
    
    0 讨论(0)
  • 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<A.length; i++)
            {
                System.out.println("("+A[i]+","+B[i]+")");
            }
        }
    
        interface Swapper
        {
            void swap(int array[], int i0, int i1);
        }
    
        public static void swap(int array[], int i0, int i1)
        {
            int t = array[i0];
            array[i0] = array[i1];
            array[i1] = t;
        }
    
        // The following methods are copied from java.util.Arrays:
        public static void sort(int x[], int off, int len, Swapper swapper)
        {
            if (len < 7)
            {
                for (int i = off; i < len + off; i++)
                {
                    for (int j = i; j > 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.

    0 讨论(0)
提交回复
热议问题