Sorting ArrayList of bytes array - java

I have some code in python which does the following:
for day in server_message.keys():
for epoch in server_message[day].keys():
assert sorted(server_message[day][epoch]) == server_message[day][epoch]
I need to write that code in Java. The problem is that the structure of server_message is as such:
Map<Integer, Map<Integer, ArrayList<byte[]>>>
How can sort ArrayList of bytes? Both Arrays.sort() and Collections.sort() don't return a new sorted array instead the work on the provided array.
Is there anything in Java that I can do to solve this problem, or do I need to write my own sorting algorithm for this kind of sort? How can I compare two bytes array?

Array.sort() uses quick algorithm at back-end and I'm surprised to see why Array.sout() is not working but you can use quick sort for this.
public class QuickSort {
public static void main(String[] args) {
int i;
int[] arr={90,23,101,45,65,23,67,89,34,23};
quickSort(arr, 0, 9);
System.out.println("\n The sorted array is: \n");
for(i=0;i<10;i++)
System.out.println(arr[i]);
}
public static int partition(int a[], int beg, int end)
{
int left, right, temp, loc, flag;
loc = left = beg;
right = end;
flag = 0;
while(flag != 1)
{
while((a[loc] <= a[right]) && (loc!=right))
right--;
if(loc==right)
flag =1;
elseif(a[loc]>a[right])
{
temp = a[loc];
a[loc] = a[right];
a[right] = temp;
loc = right;
}
if(flag!=1)
{
while((a[loc] >= a[left]) && (loc!=left))
left++;
if(loc==left)
flag =1;
elseif(a[loc] <a[left])
{
temp = a[loc];
a[loc] = a[left];
a[left] = temp;
loc = left;
}
}
}
returnloc;
}
static void quickSort(int a[], int beg, int end)
{
int loc;
if(beg<end)
{
loc = partition(a, beg, end);
quickSort(a, beg, loc-1);
quickSort(a, loc+1, end);
}
}
}

I think your problem is to sort an array of bytes (byte[]) and not a list of arrays of bytes (List<byte[]>) which doesn't make any sense.
If you want to get a sorted array of bytes without modifying the existing one you can clone the original array before :
byte[] bytes = {0, 23, 127, -12 };
byte[] clone = bytes.clone();
Arrays.sort(clone);

Related

QuickSort not working, think swap is the issue, Disclaimer I must use the quicksort method provided to me

try {
for (i = 0; i < data.length; i++) {
working[i] = data[i];
}
FileWriter fw3 = new FileWriter("quicksort.dat");
long startTime3 = System.nanoTime();
quickSort(working,0, working.length - 1);
long endTime3 = System.nanoTime();
long totalTime3 = endTime3 - startTime3;
System.out.println("The time to complete the quick sort was :" + totalTime3 + " nano seconds");
for (i = 0; i < working.length; i++) {
fw3.write(Integer.toString(working[i]) + "\n");
}
System.out.println("The file has been sorted by quick sort and output to quicksort.dat \n");
fw3.close();
} catch (IOException e) {
System.out.println(e);
}
static void quickSort(int data[], int left, int right) {
int i, j;
int partition;
if (right > left) {
partition = data[right];
i = left - 1;
j = right;
for (;;) {
while (data[++i] < partition);
while (data[--j] > partition);
if (i >= j) {
break;
}
swap(data[i], data[j]);
swap(data[i], data[right]);
quickSort(data, left, i - 1);
quickSort(data, i + 1, right);
}
}
}
static void swap(int left, int right) {
int array[] = new int[19];
int temp = array[left];
array[left] = array[right];
array[right]=temp;
This is just snippets of the code whole program is other sorts. I get an out bounds error every time it gets down to the quicksort function. I use 19 as my array because that is how big the file is I have tried 20 to see if it fixes it with no luck.
EDIT: I provided updated code down below to reflect changes that were made I still get an out of bounds error.
static void quickSort(int data[], int left, int right) {
int i, j;
int partition;
if (right > left) {
partition = data[right];
i = left - 1;
j = right;
for (;;) {
while (data[++i] < partition);
while (data[--j] > partition);
if (i >= j) {
break;
}
swap(data, i, j);
swap(data, i, right);
quickSort(data, left, i - 1);
quickSort(data, i + 1, right);
}
}
}
static void swap(int array[], int left, int right) {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
You have declared swap as :
void swap(int left, int right)
So the arguments are the indexes into the array.
However, you call it with :
swap(data[i], data[j]);
So you are passing the VALUES in the array.
Try changing the call to :
swap(i, j);
EDIT TO ADD:
It must be pointed out that the issue above is just ONE issue with the sorting algorithm presented. Another problem is that the swap algorithm does not actually swap anything. It creates a local array variable array, operates on that and then returns (so discarding that local variable).
If your assignment is to output a sorted list of numbers, and that the numbers must be sorted using the sorting code presented - then that assignment is impossible because the sorting code presented is hopelessly flawed as a sorting algorithm; it does NOT sort (as you have found yourself), and has blatant severe issues compared to a correct implementation of quicksort (eg, you can compare to the answer here : https://stackoverflow.com/a/63811974/681444 )
EDIT TO ADD FOLLOWING REVISED CODE:
The revised sorting code is STILL hopelessly busted. It is not a correct implementation of QuickSort, and still does not sort correctly.
For example, I tried running it with the final element being the largest :
int data[] = {23, 8, 19, 35, 2, 12, 7, 64 };
Result : No sorting - the method hit the if (i >= j) {break;} with i==7 and j==6 straight off and so did nothing.
By contrast, the method in the answer I linked to above sorted correctly, so you can compare the method you have been given against that - or against other established articles (eg, do an internet search for java quicksort, there are plenty around)
As already noted by 'racraman', the sort definitely requires fixing.
Try re-implementing the sort function with the following method signature.
void sort(int[] arr, int leftIndex, int rightIndex) {
// swap code goes here
}

Finding Max of an array using Recursion

So it's pretty simple to find the max of an array using a for loop or a while loop, but I wanted to try it out with recursion. For some reason, the substring doesn't work - it says "cannot find symbol". Why is this? My strategy is continue subdividing and comparing the two sides until there is only one left which should be the max....am I doing it right? Thanks
public static int max(int[] array) {
if (array.length == 1) {
return array[0];
} else {
int mid = (array.length) / 2;
int leftmax = max(array.substring(0, mid));
int rightmax = max(array.substring(mid, array.length));
if (leftmax > rightmax) {
return leftmax;
} else {
return rightmax;
}
}
}
You are going to want to use Arrays.copyOfRange. Substring isn't going to work on an array.
int[] firstHalf = Arrays.copyOfRange(original, 0, original.length/2);
int[] secondHalf = Arrays.copyOfRange(original, original.length/2, original.length);
I can't comment on your algorithm.
Since array is of type int[] not String, you cannot use substring(). Instead, keep track of which indexes you are searching through. Copying the array each iteration is a waste of both space and time.
int max( int[] array ){ return max( array, 0, array.length - 1 ); }
int max( int[] array, int low, int high )
{
if (low == high) {
return array[low];
}
else {
int mid = (high + low) / 2;
int leftmax = max(array, low, mid );
int rightmax = max(array, mid, high );
if (leftmax > rightmax) {
return leftmax;
}
else {
return rightmax;
}
}
}

Is there a space efficient implementation of mergesort?

I just coded up this working version of mergesort:
static int[] merge(int[] first, int[] second){
int totalsize = first.length + second.length;
int[] merged_array = new int[totalsize];
int i = 0, firstpointer = 0, secondpointer = 0;
while(i < totalsize){
if(firstpointer == first.length){
merged_array[i] = second[secondpointer];
++secondpointer;
}
else if(secondpointer == second.length){
merged_array[i] = first[firstpointer];
++firstpointer;
}
else if(first[firstpointer] < second[secondpointer]){
merged_array[i] = first[firstpointer];
++firstpointer;
}
else{
merged_array[i] = second[secondpointer];
++secondpointer;
}
++i;
}
return merged_array;
}
static int[] mergesort(int[] array){
if(array.length == 1){
return array;
}
else{
int length = array.length;
int[] first = Arrays.copyOfRange(array, 0, (int) length / 2);
int[] second = Arrays.copyOfRange(array, (int) length / 2, length);
return merge(mergesort(first), mergesort(second));
}
}
However, if you notice, I use the copyOfRange function which creates a new array that is a copy of a certain portion of the parent array. Is there a mergesort implementation in java that is more space efficient than this?
Duplicate of: How to sort in-place using the merge sort algorithm?
Summary: Yes, there are memory-efficient merge-sorts, but they are either a) very complicated, or b) not time-efficient: O(n^2 log n)
Basically, don't bother. It's not actually that much memory that you're saving, and if you really want to, just use quicksort instead.

How to sort an array of ints using a custom comparator?

I need to sort an array of ints using a custom comparator, but Java's library doesn't provide a sort function for ints with comparators (comparators can be used only with objects). Is there any easy way to do this?
If you can't change the type of your input array the following will work:
final int[] data = new int[] { 5, 4, 2, 1, 3 };
final Integer[] sorted = ArrayUtils.toObject(data);
Arrays.sort(sorted, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
// Intentional: Reverse order for this demo
return o2.compareTo(o1);
}
});
System.arraycopy(ArrayUtils.toPrimitive(sorted), 0, data, 0, sorted.length);
This uses ArrayUtils from the commons-lang project to easily convert between int[] and Integer[], creates a copy of the array, does the sort, and then copies the sorted data over the original.
How about using streams (Java 8)?
int[] ia = {99, 11, 7, 21, 4, 2};
ia = Arrays.stream(ia).
boxed().
sorted((a, b) -> b.compareTo(a)). // sort descending
mapToInt(i -> i).
toArray();
Or in-place:
int[] ia = {99, 11, 7, 21, 4, 2};
System.arraycopy(
Arrays.stream(ia).
boxed().
sorted((a, b) -> b.compareTo(a)). // sort descending
mapToInt(i -> i).
toArray(),
0,
ia,
0,
ia.length
);
You can use IntArrays.quickSort(array, comparator) from fastutil library.
If you don't want to copy the array (say it is very large), you might want to create a wrapper List<Integer> that can be used in a sort:
final int[] elements = {1, 2, 3, 4};
List<Integer> wrapper = new AbstractList<Integer>() {
#Override
public Integer get(int index) {
return elements[index];
}
#Override
public int size() {
return elements.length;
}
#Override
public Integer set(int index, Integer element) {
int v = elements[index];
elements[index] = element;
return v;
}
};
And now you can do a sort on this wrapper List using a custom comparator.
You don't need external library:
Integer[] input = Arrays.stream(arr).boxed().toArray(Integer[]::new);
Arrays.sort(input, (a, b) -> b - a); // reverse order
return Arrays.stream(input).mapToInt(Integer::intValue).toArray();
By transforming your int array into an Integer one and then using public static <T> void Arrays.sort(T[] a,
Comparator<? super T> c) (the first step is only needed as I fear autoboxing may bot work on arrays).
java 8:
Arrays.stream(new int[]{10,4,5,6,1,2,3,7,9,8}).boxed().sorted((e1,e2)-> e2-e1).collect(Collectors.toList());
If you are interested with performance and reducing number of object created on the way consider using implementation from eclipse collections.
It uses custom IntComparator, which operates on primitives thus no boxing is required.
Here is some code (it's actually not Timsort as I originally thought, but it does work well) that does the trick without any boxing/unboxing. In my tests, it works 3-4 times faster than using Collections.sort with a List wrapper around the array.
// This code has been contributed by 29AjayKumar
// from: https://www.geeksforgeeks.org/sort/
static final int sortIntArrayWithComparator_RUN = 32;
// this function sorts array from left index to
// to right index which is of size atmost RUN
static void sortIntArrayWithComparator_insertionSort(int[] arr, IntComparator comparator, int left, int right) {
for (int i = left + 1; i <= right; i++)
{
int temp = arr[i];
int j = i - 1;
while (j >= left && comparator.compare(arr[j], temp) > 0)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
// merge function merges the sorted runs
static void sortIntArrayWithComparator_merge(int[] arr, IntComparator comparator, int l, int m, int r) {
// original array is broken in two parts
// left and right array
int len1 = m - l + 1, len2 = r - m;
int[] left = new int[len1];
int[] right = new int[len2];
for (int x = 0; x < len1; x++)
{
left[x] = arr[l + x];
}
for (int x = 0; x < len2; x++)
{
right[x] = arr[m + 1 + x];
}
int i = 0;
int j = 0;
int k = l;
// after comparing, we merge those two array
// in larger sub array
while (i < len1 && j < len2)
{
if (comparator.compare(left[i], right[j]) <= 0)
{
arr[k] = left[i];
i++;
}
else
{
arr[k] = right[j];
j++;
}
k++;
}
// copy remaining elements of left, if any
while (i < len1)
{
arr[k] = left[i];
k++;
i++;
}
// copy remaining element of right, if any
while (j < len2)
{
arr[k] = right[j];
k++;
j++;
}
}
// iterative sort function to sort the
// array[0...n-1] (similar to merge sort)
static void sortIntArrayWithComparator(int[] arr, IntComparator comparator) { sortIntArrayWithComparator(arr, lIntArray(arr), comparator); }
static void sortIntArrayWithComparator(int[] arr, int n, IntComparator comparator) {
// Sort individual subarrays of size RUN
for (int i = 0; i < n; i += sortIntArrayWithComparator_RUN)
{
sortIntArrayWithComparator_insertionSort(arr, comparator, i, Math.min((i + 31), (n - 1)));
}
// start merging from size RUN (or 32). It will merge
// to form size 64, then 128, 256 and so on ....
for (int size = sortIntArrayWithComparator_RUN; size < n; size = 2 * size)
{
// pick starting point of left sub array. We
// are going to merge arr[left..left+size-1]
// and arr[left+size, left+2*size-1]
// After every merge, we increase left by 2*size
for (int left = 0; left < n; left += 2 * size)
{
// find ending point of left sub array
// mid+1 is starting point of right sub array
int mid = Math.min(left + size - 1, n - 1);
int right = Math.min(left + 2 * size - 1, n - 1);
// merge sub array arr[left.....mid] &
// arr[mid+1....right]
sortIntArrayWithComparator_merge(arr, comparator, left, mid, right);
}
}
}
static int lIntArray(int[] a) {
return a == null ? 0 : a.length;
}
static interface IntComparator {
int compare(int a, int b);
}
Here is a helper method to do the job.
First of all you'll need a new Comparator interface, as Comparator doesn't support primitives:
public interface IntComparator{
public int compare(int a, int b);
}
(You could of course do it with autoboxing / unboxing but I won't go there, that's ugly)
Then, here's a helper method to sort an int array using this comparator:
public static void sort(final int[] data, final IntComparator comparator){
for(int i = 0; i < data.length + 0; i++){
for(int j = i; j > 0
&& comparator.compare(data[j - 1], data[j]) > 0; j--){
final int b = j - 1;
final int t = data[j];
data[j] = data[b];
data[b] = t;
}
}
}
And here is some client code. A stupid comparator that sorts all numbers that consist only of the digit '9' to the front (again sorted by size) and then the rest (for whatever good that is):
final int[] data =
{ 4343, 544, 433, 99, 44934343, 9999, 32, 999, 9, 292, 65 };
sort(data, new IntComparator(){
#Override
public int compare(final int a, final int b){
final boolean onlyNinesA = this.onlyNines(a);
final boolean onlyNinesB = this.onlyNines(b);
if(onlyNinesA && !onlyNinesB){
return -1;
}
if(onlyNinesB && !onlyNinesA){
return 1;
}
return Integer.valueOf(a).compareTo(Integer.valueOf(b));
}
private boolean onlyNines(final int candidate){
final String str = String.valueOf(candidate);
boolean nines = true;
for(int i = 0; i < str.length(); i++){
if(!(str.charAt(i) == '9')){
nines = false;
break;
}
}
return nines;
}
});
System.out.println(Arrays.toString(data));
Output:
[9, 99, 999, 9999, 32, 65, 292, 433, 544, 4343, 44934343]
The sort code was taken from Arrays.sort(int[]), and I only used the version that is optimized for tiny arrays. For a real implementation you'd probably want to look at the source code of the internal method sort1(int[], offset, length) in the Arrays class.
I tried maximum to use the comparator with primitive type itself. At-last i concluded that there is no way to cheat the comparator.This is my implementation.
public class ArrSortComptr {
public static void main(String[] args) {
int[] array = { 3, 2, 1, 5, 8, 6 };
int[] sortedArr=SortPrimitiveInt(new intComp(),array);
System.out.println("InPut "+ Arrays.toString(array));
System.out.println("OutPut "+ Arrays.toString(sortedArr));
}
static int[] SortPrimitiveInt(Comparator<Integer> com,int ... arr)
{
Integer[] objInt=intToObject(arr);
Arrays.sort(objInt,com);
return intObjToPrimitive(objInt);
}
static Integer[] intToObject(int ... arr)
{
Integer[] a=new Integer[arr.length];
int cnt=0;
for(int val:arr)
a[cnt++]=new Integer(val);
return a;
}
static int[] intObjToPrimitive(Integer ... arr)
{
int[] a=new int[arr.length];
int cnt=0;
for(Integer val:arr)
if(val!=null)
a[cnt++]=val.intValue();
return a;
}
}
class intComp implements Comparator<Integer>
{
#Override //your comparator implementation.
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o1.compareTo(o2);
}
}
#Roman:
I can't say that this is a good example but since you asked this is what came to my mind.
Suppose in an array you want to sort number's just based on their absolute value.
Integer d1=Math.abs(o1);
Integer d2=Math.abs(o2);
return d1.compareTo(d2);
Another example can be like you want to sort only numbers greater than 100.It actually depends on the situation.I can't think of any more situations.Maybe Alexandru can give more examples since he say's he want's to use a comparator for int array.

Quicksort algorithm program in Java

I'm trying to implement QuickSort algorithm program in Java, but I'm getting incorrect answer.
public class QuickSort {
public static void main(String[] args){
int arr[]={12,34,22,64,34,33,23,64,33};
int i=0;
int j=arr.length;
while(i<j){
i=quickSort(arr,i,i+1,j-1);
}
for(i=0;i<arr.length;i++)
System.out.print(arr[i]+" ");
}
public static int quickSort(int arr[],int pivot,int i,int j){
if(i>j) {
swap(arr,pivot,j);
return i;
}
while(i<arr.length&&arr[i]<=arr[pivot]) {
i++;
}
while(j>=1&&arr[j]>=arr[pivot]) {
j--;
}
if(i<j)
swap(arr,i,j);
return quickSort(arr,pivot,i,j);
}
public static void swap(int[] arr,int i,int j) {
int temp;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
The above program giving me the output as: 12 23 22 33 34 33 64 34 64
Could anyone please tell me how can I get my desire result?
The problem is that this is not really how quicksort works. Quicksort is a recursive algorithm that should only be called once from outside of itself. The idea is that at each iteration, you partition the array into two halves - the left half contains all elements less than the pivot, and the right half contains all elements greater than / equal to the pivot. Then you quicksort the two halves, and finally put the pivot in the middle.
If the side that you are quicksorting is less than 3 elements long, you can just swap the two elements or leave them, and that part of the array is done.
But it doesn't look like your code is doing that at all - you are calling Quicksort 6 times from your client, and within the quicksort function you are making at most one swap. So this is not a case where someone is going to be able to look at your code and debug it by telling you to move a swap or something. You need to revisit your logic.
Check out the Wikipedia diagram for a visual example of what is supposed to happen in a single iteration:
http://en.wikipedia.org/wiki/File:Partition_example.svg
There are open source implementations of quicksort in Apache Harmony and Apache Mahout, probably amongst many others. You can read them.
public static int partition(int[] a, int p, int r){
int i=p,j=r,pivot=a[r];
while(i<j){
while(i<r && a[i] <= pivot){
i++;
}
while(j>p && a[j]>pivot){
j--;
}
if(i<j){
swap(a, i, j);
}
}
return j;
}
public static void quickSort(int[] a, int p, int r){
if(p<r){
int q=partition(a, p, r);
if(p==q){
quickSort(a, p+1, r);
}else if(q==r){
quickSort(a, p, r-1);
}else {
quickSort(a, p, q);
quickSort(a, q+1, r);
}
}
}
public static void swap(int[] a, int p1, int p2){
int temp=a[p1];
a[p1]=a[p2];
a[p2]=temp;
}
here is a quicksort algorithm
package drawFramePackage;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Random;
public class QuicksortAlgorithm {
ArrayList<AffineTransform> affs;
ListIterator<AffineTransform> li;
Integer count, count2;
/**
* #param args
*/
public static void main(String[] args) {
new QuicksortAlgorithm();
}
public QuicksortAlgorithm(){
count = new Integer(0);
count2 = new Integer(1);
affs = new ArrayList<AffineTransform>();
for (int i = 0; i <= 128; i++){
affs.add(new AffineTransform(1, 0, 0, 1, new Random().nextInt(1024), 0));
}
affs = arrangeNumbers(affs);
printNumbers();
}
public ArrayList<AffineTransform> arrangeNumbers(ArrayList<AffineTransform> list){
while (list.size() > 1 && count != list.size() - 1){
if (list.get(count2).getTranslateX() > list.get(count).getTranslateX()){
list.add(count, list.get(count2));
list.remove(count2 + 1);
}
if (count2 == list.size() - 1){
count++;
count2 = count + 1;
}
else{
count2++;
}
}
return list;
}
public void printNumbers(){
li = affs.listIterator();
while (li.hasNext()){
System.out.println(li.next());
}
}
}
also available with description at nathan's computer knowledge with a description
[code]
[/code]
``
Your loop is not working properly. Refer the code which is solve your problem about Quick Sort
static void quickSort (int[] numbers, int low, int high)
{
int i=low;
int j=high;
int temp;
int middle=numbers[(low+high)/2];
while (i<j) {
while (numbers[i]<middle) {
i++;
}
while (numbers[j]>middle) {
j--;
}
if (i<=j) {
temp=numbers[i];
numbers[i]=numbers[j];
numbers[j]=temp;
i++;
j--;
}
}
if (low<j) {
quickSort(numbers, low, j);
}
if (i<high) {
quickSort(numbers, i, high);
}
}
Refer Quick sort.
Please find comprehensive working code for quick sort algorithm implemented in Java here,
http://tech.bragboy.com/2010/01/quick-sort-in-java.html

Categories