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
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);
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();
}
}
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;
}
}
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++;
}
}
}
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));
}
}
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.