You are on page 1of 3

/**

*
* The only problem with this below process is if two elements has same count,
* then it doesn't preserve the order of those elements, the way they appeared.
* /
public class SortByFrequency {

int[] arr;
int[][] elements;

public SortByFrequency(int[] arr, int[][] elements) {


this.arr = arr;
this.elements = elements;
}

public void sortByFrequency() {


System.out.println("Array before sorting: " + Arrays.toString(arr));

// array elements are sorted


sort(arr);
System.out.println("\nArray after sorting: " + Arrays.toString(arr));

/*
* now we will create a 2-D array and store the elements in the first
* column and in the second column we store their repetition count.
* Store the first element of the sorted array in the
*/
int fIndex = 0;
elements[fIndex][0] = arr[0];
elements[fIndex][1] = 1;

for (int i = 1; i < arr.length; i++) {


if (arr[i] == arr[i - 1]) {
/*
* if the current element value if equal to it's previous then
* storing the count in the second column, hence using
* elements[fIndex][1]
*
* We do not increment the fIndex value here, as the same
* element may still be present in the next iteration and we
* still need to increment the count in the second column as
* long as the element will be present.
*/
elements[fIndex][1] = elements[fIndex][1] + 1;
} else {
/*
* if the current element value is not equal to it's previous
* element, then we need to store this element in a new row
* first column, so incrementing the row count here.
*/
fIndex++;
elements[fIndex][0] = arr[i];
elements[fIndex][1] = 1;
}
}
System.out.println("fIndex " + fIndex);

/*
* Printing 2-D array after creating
*/
System.out.println("Printing 2-D array after creating:");
for (int i = 0; i <= fIndex; i++) {
for (int j = 0; j < 2; j++) {
System.out.print(elements[i][j] + " ");
}
System.out.println();
}

/*
* Now we need to sort this two dimensional array based on it's
* occurrence. Hence we need to write another sort method which will
* take a two dimensional array as input.
*/
sort(elements, fIndex);

/*
* Now we are done with sorting the 2-D array elements as well. Need to
* print the first column of the 2-D array. For every element we need to
* check it's corresponding repetition count in the second column &
* print accordingly.
*/

System.out.println();
for (int i = 0; i <= fIndex; i++) {
for (int j = 0; j < elements[i][1]; j++) {
System.out.print(elements[i][0] + " ");
}
}
}

/**
* Implementing bubble sort
* @param elements
* @param fIndex
* @return
*/
public int[][] sort(int elements[][], int fIndex) {
/*
* In a 2-D array, each row represents an array. Here in this case, we
* have a 2-D array with n rows and two columns.
*/

for (int i = 0; i <= fIndex; i++) {


for (int j = 1; j <= fIndex - i; j++) {
if (elements[j][1] < elements[j - 1][1]) {
swapTwoDArray(j, j - 1);
}
}
}
return elements;
}

/**
* Implementing bubble sort
*
* @param arr
* @return
*/
public int[] sort(int[] arr) {
long startTime = System.nanoTime();

int passCounter;
for (int i = 0; i < arr.length; i++) {
passCounter = 0;
for (int j = 1; j < arr.length - i; j++) {
if (arr[j - 1] > arr[j]) {
passCounter++;
swap(j - 1, j);
}
}
System.out.println("For i = " + i + "--> passCounter value: "
+ passCounter);

if (passCounter == 0) {
System.out.println("Breaking the outer loop");
break;
}
}
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);
System.out.println();
return arr;
}

/** Utility method to swap two numbers in array */


public void swap(int from, int to) {
int temp = arr[from];
arr[from] = arr[to];
arr[to] = temp;
}

/** Utility method to swap two numbers in array */


public void swapTwoDArray(int from, int to) {
int temp[] = elements[from];
elements[from] = elements[to];
elements[to] = temp;
}

public static void main(String[] args) {


int[] arr = { 2, 5, 2, 8, 5, 6, 8, 8 };
int[][] elements = new int[arr.length][2];
SortByFrequency frequency = new SortByFrequency(arr, elements);
frequency.sortByFrequency();
}
}

You might also like