Rearranging java array elements - java

What exactly am I doing wrong here and how do I fix it (please answer like I'm 5 as I am new to java and StackOverflow). The xyzToFront method is the one that should be responsible for the issue. I know there is a code that helps with rearranging/makes it simpler, but I am trying to work with/create my own algorithm according to what I learned.
Here is what I am getting:
+[cat, dog, horse, zebra, zebra]
Expected: [cat, dog, horse, zebra, zebra]
+2
Expected: 2
+3
Expected: 3
-[xantus, xantus, yak, ape, dog, cat]
Expected: [xantus, zebra, yak, ape, dog, cat
Here is the code:
// Complete the methods below. These methods manipulate Arrays of
Strings
// Need help starting this question? In the lesson titled //
"Starting points: Problem Set Questions", go to the // problem titled
"Problem Set 7 - Question 1" for some tips on // how to begin.
import java.util.Arrays;
public class ArrayMethods {
String[] list; //instance variable
/**
* Constructor for objects of class ArrayMethods
*/
public ArrayMethods(String[] list)
{
// initialise instance variables
this.list = list;
}
/**
* Determines if the array is sorted (do not sort)
* When Strings are sorted, they are in alphabetical order
* Use the compareTo method to determine which string comes first
* You can look at the String compareTo method in the Java API
* #return true if the array is sorted, else false.
*/
public boolean isSorted()
{
boolean sorted = true;
// TODO: Write the code to loop through the array and determine that each
// successive element is larger than the one before it
for (int i = 1; i< list.length; i++){
if((list[i].compareTo(list[i-1]))>0){
sorted = false;
}
}
return sorted;
}
/**
* Replaces all but the first and last with the larger of its to neighbors
* You can use the compareTo to determine which string is larger (later in alphabetical
* order).
*/
public void replaceWithLargerNeighbor()
{
for(int i = 1; i<list.length-1; i++){
if ((list[i-1].compareTo(list[i+1]))> 0){
list[i] = list[i-1];
}
else if(list[i-1].compareTo(list[i+1]) < 0){
list[i] = list[i+1];
}
}
}
/**
* Gets the number of duplicates in the array.
* (Be careful to only count each duplicate once. Start at index 0. Does it match any of the other element?
* Get the next word. It is at index i. Does it match any of the words with index > i?)
* #return the number of duplicate words in the array.
*/
public int countDuplicates()
{
int duplicates = 0;
for(int i = 0; i <list.length-1; i++){
for(int j = i+1; j < list.length; j++){
if(list[i].equals(list[j])){
duplicates++;
}
}
}
return duplicates;
}
/**
* Moves any word that starts with x, y, or z to the front of the array, but
* otherwise preserves the order
*/
public void xyzToFront()
{
String index = "";
int insertAt = 0;
for(int i = 0; i<list.length; i++){
boolean startsWith = (list[i].startsWith("x") || list[i].startsWith("y") || list[i].startsWith("z"));
if(startsWith){
index = list[i];
for(int j = i; j>0; j--){
list[j] = list[j-1];
}
list[insertAt] = index;
insertAt++;
}
}
}
/**
* gets the string representation of this array
* #return a string representation of the array. (do this with Arrays.toString(list))
*/
public String toString()
{
return Arrays.toString(list);
} }
The following is the tester method that does not work with my answer for xyzToFront:
String[] animals4 = {"ape", "dog", "xantus", "zebra", "cat", "yak"};
zoo = new ArrayMethods(animals4); zoo.xyzToFront();
System.out.println(zoo.toString()); System.out.println("Expected:
[xantus, zebra, yak, ape, dog, cat]");

Looks like it was "insertAt" and not "0" as I put before. I guess somehow it was overwriting eachother.
for(int j = i; j>insertAt; j--){

Related

iterating through multidimensional ArrayList

I am confused regarding iterating through a multidimensional ArrayList .
I saw some topics about it and they seem complicated. in specific the accepted
answer here:
How to iterate through two dimensional ArrayList using iterator?
can it be as in this method? which iterates through the arrayList and copy the value to an array:
private void reassembleArray(int[] array, ArrayList<ArrayList<Integer>> buckets) {
Iterator<ArrayList<Integer>> it = buckets.iterator();
int i = 0;
while (it.hasNext()) {
ArrayList<Integer> intList = it.next();
Iterator<Integer> itInteger = intList.iterator();
while (itInteger.hasNext()) {
array[i] = itInteger.next();
i++;
}
}
}
are there any dangers or side effects for using this simple form?
this is the complete program which is an implementation of a sort algorithm called radix sort.
import java.util.ArrayList;
import java.util.Iterator;
/**
* Radix sort implementation
*/
public class RadixSort {
/**
* Runs the program
*/
public static void main(String[] args) {
int[] array = {315, 418, 591, 260, 533, 58, 976, 938,};
System.out.println("Radix sort implementation");
printArray(array);
sort(array, 3); // 3 is the maximun number of digits in all array elements to sort
printArray(array);
}
/*
* sort array of integers using radix sort algorithm
* #param array The array
* #param n the maximum number of digits in array elements
*/
private void sort(int[] array, int n) {
int digitNumber = 0;
while (digitNumber < n) {
ArrayList<ArrayList<Integer>> buckets = initBuckets();
// store each element in the bucket corresponding to the (digitNumber + 1)th
// digit of that element
for (int i = 0; i < array.length; i++) {
int value = array[i];
int bucket = (value / (int) (Math.pow(10, digitNumber))) % 10;
buckets.get(bucket).add(value);
}
reassembleArray(array, buckets);
digitNumber++;
}
}
/*
* Initialize buckets ArrayList
* #return The buckets ArrayList
*/
private ArrayList<ArrayList<Integer>> initBuckets() {
ArrayList<ArrayList<Integer>> buckets = new ArrayList<ArrayList<Integer>>();
// a bucket for each digit from 0 to 9
for(int i = 0; i < 10; i++) {
buckets.add(new ArrayList<Integer>());
}
return buckets;
}
/*
* Reassemble the array
* #param array The array
* #param buckets The buckets
*/
private void reassembleArray(int[] array,
ArrayList<ArrayList<Integer>> buckets) {
Iterator<ArrayList<Integer>> it = buckets.iterator();
int i = 0;
while (it.hasNext()) {
ArrayList<Integer> intList = it.next();
Iterator<Integer> itInteger = intList.iterator();
while (itInteger.hasNext()) {
array[i] = itInteger.next();
i++;
}
}
}
/*
* Prints an array of integers on a single line
* #param array The array
*/
private void printArray(int[] array) {
System.out.print("array: {");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ((i == array.length - 1) ?"" : ", "));
}
System.out.println("}");
}
}
The algorithm simply requires sorting the collection through a number of steps,
first sort the collection according to the first digit to the right and have all the elements that in buckest of 0 - 9 according to that last digit while maintaining the initial order of the collection, then starting from bucket 0 reassemle the collection again and proceed to sorting according to the next digit to the left and so on.
the program does work and sorts the collection fine.
I bet the output you get is not the same one as you expect since the following line results in:
array[i] = itInteger.next();
Type mismatch: cannot convert from Integer to int[]
As far as I understand you want to convert List<List<Integer>> structure to the array of the same type. You also need to map Integer to int using Stream::mapToInt:
int array[][] = new int[buckets.size()][];
IntStream.range(0, buckets.size())
.forEach(i -> array[i] = buckets.get(i)
.stream()
.mapToInt(j -> j.intValue())
.toArray());
System.out.println(Arrays.deepToString(array)); // Prints the very same output
Also, you don't need to use Iterator, however if you insist on it:
int outerIndex = 0;
while (outerIterator.hasNext()) {
List<Integer> list = outerIterator.next();
Iterator<Integer> innerIterator = list.iterator();
array[outerIndex] = new int[list.size()];
int innerIndex = 0;
while (innerIterator.hasNext()) {
array[outerIndex][innerIndex] = innerIterator.next().intValue();
innerIndex++;
}
outerIndex++;
}
Are there any dangers or side effects for using this simple form?
Yes, both of the solutions are since they don't amend the original resource of input nor affect another resource.
Your code will be clearer if you use enhanced for loops instead of iterators:
int i = 0;
for (List<Integer> intList : buckets) {
for (int value : intList) {
arr[i++] = value;
}
}

Returning a value from one method to another method

/* Assume as precondition that the list of players is not empty.
* Returns the winning score, that is, the lowest total score.
* #return winning score
*/
public int winningScore() {
Player thePlayer = players.get(0);
int result = thePlayer.totalScore();
for (int i = 0; i < players.size(); i++){
int p = players.get(i).totalScore();
if (p < result) {
result = players.get(i).totalScore();
}
}
return result;
}
/* Returns the list of winners, that is, the names of those players
* with the lowest total score.
* The winners' names should be stored in the same order as they occur
* in the tournament list.
* If there are no players, return empty list.
* #return list of winners' names
*/
public ArrayList<String> winners() {
ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i < players.size(); i++)
if (!players.isEmpty())
return result;
}
As it states in the comments, I am trying to return the winningScore() result in the winners method so it returns the the winner/winners names.
I have managed to only return all of the winners but am a little confused if it should be calling from the winningScore() method or not?
I understand my current code is incorrect for winners
Any push/hint in the right direction would be appreciated! Thanks!
What you want to do is to find all player objects with the winning score in your winners method.
To do this you need to first calculate the winning score by calling
your winningScore method.
Next you find all player objects whose totalScore equals the
previously calculated winning score. You want to return those.
The resulting code for your winners method would then look like this:
public ArrayList<String> winners() {
ArrayList<String> result = new ArrayList<String>();
int winningScore = winningScore();
for (int i = 0; i < players.size(); i++)
if (players.get(i).totalScore() == winningScore)
result.add(players.get(i).getName())
return result;
}
If you want to simplify the code, you can substitute the for loop by a loop using the ArrayList iterator like this, since you do not use the index variable i:
for (Player player : players) {
if (player.totalScore() == winningScore)
result.add(player.getName())
}

ArrayList throwing "java.lang.ArrayIndexOutOfBoundsException"

I know from reading other questions on the forumn that Array indexing is causing the problem, but I don't know any way around it. I commented where the throw happens. The whole throw is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
at assignment4.AnagramTester.main(AnagramTester.java:36)
If anyone has any ideas how I can make this work, let me know. Also, I don't think any more of my methods are relevant in solving this but I can put them here if needed.
/*areAnagrams
* parameters: sorted strings x & y
* returns boolean
* implements sort method
*/
public static boolean areAnagrams(String x, String y)
{
if(sort(x).equals(sort(y)))
return true;
return false;
}
/*
* This function takes a string array and finds the largest anagram group.
* AnagramComparator.insertionSort() sorts the array by placing anagrams together,
* so no sorting is needed.
* I use ArrayList because I want to be able to freely add to the string array.
* returns a new String[]
*/
public static String[] getLargestAnagramGroup(String[] input)
{
String[] s=input;
AnagramComparator.insertionSort(s, new AnagramComparator());
int largestCount = 0, tempCount=1;
ArrayList<String> largest= new ArrayList<String>();
ArrayList<String> temp= new ArrayList<String>();
for(int i=0; i<s.length; i++)
{
//since it's already sorted, we need only to compare.
//add
temp.add(s[i]);
//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 35
if (areAnagrams(s[i],s[i+1])) //at assignment4.AnagramUtil.getLargestAnagramGroup(AnagramUtil.java:82)
{
//add s[i+1] to array list
temp.add(s[i+1]);
tempCount++;
}
else
{
//if tempcount> largestcount, empty contents of largest and make temp largest
if (tempCount>largestCount)
{
if(!largest.isEmpty())
largest.clear();
largest=temp;
largestCount=tempCount;
}
//reset tempcount
tempCount=1;
}
}
String[] result= new String[largest.size()];
for (int j=0;j<largest.size();j++)
result[j]=largest.get(j);
return result;
}
your problem is here:
areAnagrams(s[i],s[i+1])
this will fail when i = s.length - 1 because of i + 1 (when i = s.length it is out of bounds, as length returns the number of elements, yet array index starts at 0)
change
for(int i=0; i<s.length; i++)
to
for(int i=0; i<s.length - 1; i++)
Try changing this line:
for(int i=0; i<s.length; i++)
to this:
for(int i=0; i<s.length-1; i++)
You have a loop
for(int i=0; i<s.length; i++) {...
which means that for the maximum allowable value of i, s[i] will be the last element in s.
But within the loop you are referencing s[i + 1], which is past the end of s.

A Sorted Integer List

So the original code is
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
and
// ***************************************************************
// ListTest.java
//
// A simple test program that creates an IntList, puts some
// ints in it, and prints the list.
//
// ***************************************************************
import java.util.Scanner ;
public class ListTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
IntList myList = new IntList(10);
int count = 0;
int num;
while (count < 10) {
System.out.println("Please enter a number, enter 0 to quit:");
num = scan.nextInt();
if (num != 0) {
myList.add(num);
count++;
} else {
break;
}
}
System.out.println(myList);
}
}
I need to change the add method to sort from lowest to highest. This is what I tried doing.
// An (unsorted) integer list class with a method to add an
// integer to the list and a toString method that returns the contents
// of the list with indices.
//
// ****************************************************************
public class IntList {
private int[] list;
private int numElements = 0;
//-------------------------------------------------------------
// Constructor -- creates an integer list of a given size.
//-------------------------------------------------------------
public IntList(int size) {
list = new int[size];
}
//------------------------------------------------------------
// Adds an integer to the list. If the list is full,
// prints a message and does nothing.
//------------------------------------------------------------
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
list[numElements] = value;
numElements++;
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
for (in i = 0; i < list.length; i++) {
}
}
}
//-------------------------------------------------------------
// Returns a string containing the elements of the list with their
// indices.
//-------------------------------------------------------------
public String toString() {
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
}
The outcome is very wrong. Any one able to steer me in the right direction? I can sort of see why what I have doesn't work, but I can't see enough to fix it.
So I realize I was not very descriptive here the first time. With the exception of the add method modifications the code was not my doing. My assignment is to only touch the add method to sort the array to print out smallest to largest. This is a beginners class and we do little to no practice my only tools for this are some basic understandings of loops and arrays.
I tried redoing it again and came up with this:
if(list[numElements-1] > value){
for(int i=0; i<numElements; i++){
if(list[i]>value){
for(int j = numElements; j>i; j-- ){
list[j] = list[j-1];
}
list[i] = value;
break;
}
}
numElements++;
}
else
{
list[numElements] = value;
numElements++;
}
my input was:8,6,5,4,3,7,1,2,9,10
the output was: 1,10,1,9,10,1,1,2,9,10
this thing is kicking my butt. I understand I want to check the input number to the array and move all numbers higher than it up one space and enter it behind those so it is sorted on entry, but doing so is proving difficult for me. I apologize if my code on here is hard to follow formatting is a little odd on here for me and time only allows for me to do my best. I think break is not breaking the for loop with i like i thought it would. Maybe that is the problem.
The biggest bug I see is using list.length in your for loop,
for(int i = 0; i <list.length; i++)
you have numElements. Also, I think it's i that needs to stop one before like,
for(int i = 0; i < numElements - 1; i++)
and then
for (int j = numElements; j > i; j--)
There are two lines that have to be moved out of the inner loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
// list[i] = value;
// break;
}
list[i] = value;
break:
}
}
In particular, the inner break means that the loop that is supposed to move all larger elements away to make room for the new value only runs once.
You might want to include Java.util.Arrays which has its own sort function:
http://www.tutorialspoint.com/java/util/arrays_sort_int.htm
Then you can do:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
}
else {
list[numElements] = value;
numElements++;
Arrays.sort(list);
//Or: Java.util.Arrays.sort(list);
}
}
As Eliott remarked, you are getting confused between list.length (the capacity of your list) and numElements (the current size of your list). Also, though, you do not need to completely sort the list on each addition if you simply make sure to insert each new element into the correct position in the first place. You can rely on the rest of the list already to be sorted. Here's a simple and fast way to do that:
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
int insertionPoint = Arrays.binarySearch(list, 0, numElements);
if (insertionPoint < 0) {
insertionPoint = -(insertionPoint + 1);
}
System.arrayCopy(list, insertionPoint, list, insertionPoint + 1,
numElements - insertionPoint);
list[insertionPoint] = value;
numElements += 1;
}
}
That will perform better (though you may not care for this assignment), and it is much easier to see what's going on, at least for me.
Here are some hints.
First, numElements indicates how many elements are currently in the list. It's best if you change it only after you have finished adding your item, like the original method did. Otherwise it may confuse you into thinking you have more elements than you really do at the moment.
There is really no need for a nested loop to do proper adding. The logic you should be following is this:
I know everything already in the list is sorted.
If my number is bigger then the biggest number (which is the one indexed by numElements-1, because the list is sorted) then I can just add my number to the next available cell in the array (indexed by numElements) and then update numElements and I'm done.
If not, I need to start from the last element in the array (careful, don't look at the length of the array. The last element is indexed by numElements-1!), going down, and move each number one cell to the right. When I hit a cell that's lower than my number, I stop.
Moving all the high numbers one cell to the right caused one cell to become "empty". This is where I'm going to put my number. Update numElements, and done.
Suppose you want to add the number 7 to this array:
┌─┬──┬──┬─┬─┐
│3│14│92│-│-│
└─┴──┴──┴─┴─┘
⬆︎ Last element
You move everything starting from the last element (92) to the right. You stop at the 3 because it's not bigger than 7.
┌─┬─┬──┬──┬─┐
│3│-│14│92│-│
└─┴─┴──┴──┴─┘
(The second element will probably still contain 14, but you're going to change that in the next step so it doesn't matter. I just put a - there to indicate it's now free for you to enter your number)
┌─┬─┬──┬──┬─┐
│3│7│14│92│-│
└─┴─┴──┴──┴─┘
⬆︎ Updated last element
This requires just one loop, without nesting. Be careful and remember that the array starts from 0, so you have to make sure not to get an ArrayIndexOutOfBoundsException if your number happens to be lower than the lowest one.
One problem I spotted is that: you are trying to insert the newly added number into the array. However your loop:
for (int i = 0; i < list.length; i++) {
if (list[i] > value) {
for (int j = list.length - 1; j > i; j--) {
list[j] = list[j - 1];
list[i] = value;
break;
}
}
}
is always looped through the total length of the array, which is always 10 in your test, rather than the actual length of the array, i.e. how many numbers are actually in the array.
For example, when you add the first element, it still loops through all 10 elements of the array, although the last 9 slots does not have value and are automatically assigned zero.
This caused your if statement always returns true:
if (list[i] > value)
if you have to write the sort algorithm yourself, use one of the commonly used sorting algorithm, which can be found in Wikipedia.
If any one was curious I finally worked it out. Thank you to everyone who replied. This is what i ended up with.
public void add(int value)
{
if(numElements == 0){
list[numElements] = value;
numElements++;
}
else{
list[numElements] = value;
for(int check = 0; check < numElements; check++){
if(list[check] > value){
for(int swap = numElements; swap> check; swap--){
list[swap] = list[swap-1];
}
list[check] = value;
break;
}
}
numElements++;
}
}
so my original is the same but we have to make another class
A Sorted Integer List
File IntList.java contains code for an integer list class. Save it to your project and study it; notice that the only things you can do are create a list of a fixed size and add an element to a list. If the list is already full, a message will be printed. File ListTest.java contains code for a class that creates an IntList, puts some values in it, and prints it. Save this to your folder and compile and run it to see how it works.
Now write a class SortedIntList that extends IntList. SortedIntList should be just like IntList except that its elements should always be in sorted order from smallest to largest. This means that when an element is inserted into a SortedIntList it should be put into its sorted place, not just at the end of the array. To do this you’ll need to do two things when you add a new element:
Walk down the array until you find the place where the new element should go. Since the list is already sorted you can just keep looking at elements until you find one that is at least as big as the one to be inserted.
Move down every element that will go after the new element, that is, everything from the one you stop on to the end. This creates a slot in which you can put the new element. Be careful about the order in which you move them or you’ll overwrite your data!
Now you can insert the new element in the location you originally stopped on.
All of this will go into your add method, which will override the add method for the IntList class. (Be sure to also check to see if you need to expand the array, just as in the IntList add() method.) What other methods, if any, do you need to override?
To test your class, modify ListTest.java so that after it creates and prints the IntList, it creates and prints a SortedIntList containing the same elements (inserted in the same order). When the list is printed, they should come out in sorted order.

php's array_multisort function equivalent in java

I was looking for an equivalent of *php's array_multisort* in java.
//array 1
ar1 = array(10, 100, 100, 0);
//array 2
ar2 = array(1, 3, 2, 4);
//calling the function
//this will sort the array at first based one the first array and then based on the
//second array so these two array are related
array_multisort(ar1, ar2);
//resultant 1st array
array(4) {
[0]=> int(0)
[1]=> int(10)
[2]=> int(100)
[3]=> int(100)
}
//resultant 2nd array
//this array has been sorted based on the first array at first
array(4) {
[0]=> int(4) // this is associative element of 0 in the first array
[1]=> int(1) //this is associative element of 10 in the first array
[2]=> int(2) //this is associative element of 1st 100 from the last in the first array
//as there are two 100's , and last one's associative value in the second
//array is smaller it will come first
[3]=> int(3)
}
how can i achieve this result using something built-in , i know how to implement it using custom code.
N.B. *Please visit this link before answering the question as that explains how the function should work*
This is a bit more complicated and can't be done without the Java standard API. So I have recycled a quicksort implementation and made it work for multiple arrays. Basically it swaps the elements when they are swapped by the partitioning of quicksort.
Here you go:
/**
* Multi-sorts the given arrays with the quicksort algorithm. It assumes that
* all arrays have the same sizes and it sorts on the first dimension of these
* arrays. If the given arrays are null or empty, it will do nothing, if just
* a single array was passed it will sort it via {#link Arrays} sort;
*/
public static void multiQuickSort(int[]... arrays) {
multiQuickSort(0, arrays);
}
/**
* Multi-sorts the given arrays with the quicksort algorithm. It assumes that
* all arrays have the same sizes and it sorts on the given dimension index
* (starts with 0) of these arrays. If the given arrays are null or empty, it
* will do nothing, if just a single array was passed it will sort it via
* {#link Arrays} sort;
*/
public static void multiQuickSort(int sortDimension, int[]... arrays) {
// check if the lengths are equal, break if everything is empty
if (arrays == null || arrays.length == 0) {
return;
}
// if the array only has a single dimension, sort it and return
if (arrays.length == 1) {
Arrays.sort(arrays[0]);
return;
}
// also return if the sort dimension is not in our array range
if (sortDimension < 0 || sortDimension >= arrays.length) {
return;
}
// check sizes
int firstArrayLength = arrays[0].length;
for (int i = 1; i < arrays.length; i++) {
if (arrays[i] == null || firstArrayLength != arrays[i].length)
return;
}
multiQuickSort(arrays, 0, firstArrayLength, sortDimension);
}
/**
* Internal multi quicksort, doing the real algorithm.
*/
private static void multiQuickSort(int[][] a, int offset, int length,
int indexToSort) {
if (offset < length) {
int pivot = multiPartition(a, offset, length, indexToSort);
multiQuickSort(a, offset, pivot, indexToSort);
multiQuickSort(a, pivot + 1, length, indexToSort);
}
}
/**
* Partitions the given array in-place and uses the end element as pivot,
* everything less than the pivot will be placed left and everything greater
* will be placed right of the pivot. It returns the index of the pivot
* element after partitioning. This is a multi way partitioning algorithm, you
* have to provide a partition array index to know which is the array that
* needs to be partitioned. The swap operations are applied on the other
* elements as well.
*/
private static int multiPartition(int[][] array, int start, int end,
int partitionArrayIndex) {
final int ending = end - 1;
final int x = array[partitionArrayIndex][ending];
int i = start - 1;
for (int j = start; j < ending; j++) {
if (array[partitionArrayIndex][j] <= x) {
i++;
for (int arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
swap(array[arrayIndex], i, j);
}
}
}
i++;
for (int arrayIndex = 0; arrayIndex < array.length; arrayIndex++) {
swap(array[arrayIndex], i, ending);
}
return i;
}
/**
* Swaps the given indices x with y in the array.
*/
public static void swap(int[] array, int x, int y) {
int tmpIndex = array[x];
array[x] = array[y];
array[y] = tmpIndex;
}
Done a little testcase to test your input from the question:
#Test
public void testMultiQuickSort() {
int[] first = new int[] { 10, 100, 100, 0 };
int[] second = new int[] { 1, 3, 2, 4 };
int[] resFirst = new int[] { 0, 10, 100, 100 };
int[] resSecond = new int[] { 4, 1, 2, 3 };
ArrayUtils.multiQuickSort(first, second);
for (int i = 0; i < first.length; i++) {
assertEquals(resFirst[i], first[i]);
assertEquals(resSecond[i], second[i]);
}
}
Seems to work ;)
BTW if you need it for an arbitrary object type, just leave a comment.
A multi-dimensional array is just an array of arrays, so iterate over the individual arrays and sort them:
int[][] marr = // your multi-dimensional array here
for (int[] arr : marr) {
Arrays.sort(arr);
}
And if, for whatever possible reason, you only want to sort the first array in the second dimension, this will do:
Arrays.sort(marr[0]);
Argh, now I understand what you want. If your elements (at least those of the first array) are unique, you can do it via a SortedMap:
if(arr1.length!=arr2.length)throw new IllegalArgumentException();
SortedMap<Integer,Integer> map = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr1.length; i++) {
map.put(arr1[i],arr2[i]);
}
int ct = 0;
for (Entry<Integer, Integer> entry : map.entrySet()) {
arr1[ct]=entry.getKey();arr2[ct]=entry.getValue();
ct++;
}
It's look like that there is not any built-in library function / class for this purpose in Java .
If you are also facing this problem like me , so far Thomas's answer about the custom code can help you.
implements Comparator or using algorithm bubble sort
Arrays.sort(stringArray); it will sort only one array
Maybe the following code will help you.
You should use Arrays.sort()
Example:
import java.util.Arrays;
String [] stringArray = {"ab", "aB", "c", "0", "2", "1Ad", "a10"};
//order Ascending
Arrays.sort(stringArray);
//Descending
Arrays.sort(stringArray, Collections.reverseOrder());

Categories

Resources