Java 2d array and Bucket sort - java

I am working on an assignment where we need to take a integer array and sort it using a Bucket Sort.
My issue comes when trying to increase to the next column, but only if there is an element already in the "bucket" already.
So, using my array below, 22 is the first element and will go in row 2 column 0, which is correct, but using i as the column is obviously not correct because it always increases the column and I eventually get an index out of bounds.
I can't wrap my head around how to correctly increase the index of the bucketArray column, only if there is an element in that position. I've tried using an additional for loop that handled the column but that didn't work either.
Any pointers in the right direction would be greatly appreciated! I'm sure also there are other ways to create a bucket sort but the assignment said to use a 2d array for each bucket so I was trying to get it to work that way.
public class BucketSort {
public static void main(String args[]) {
int intArray[] = {22, 45, 12, 8, 10, 6, 72, 81, 33, 18, 50, 14};
int eachBucket[][] = new int[10][11];
int j;
double max = 81;
int min = 6;
int divider = (int)Math.ceil((max + 1) / 10);
for(int i = 0; i < intArray.length; i++) {
j = (int)Math.floor(intArray[i] / divider);
eachBucket[j][i] = intArray[i];
}
}
}

Use the 11th element to track how many elements in the current bucket have been used, something like this
for(int i = 0; i < intArray.length; i++) {
j = (int)Math.floor(intArray[i] / divider);
eachBucket[j][eachBucket[j][10]] = intArray[i];
eachBucket[j][10]++;
}
The problem with a fixed-sized second dimension is if you have more that n elements to put into any one bucket. Probably not a problem here.

Related

Array generation - Regular, or 2D?

I'll try to keep this as short and concise as possible.
I'm working on a project, and I'm stuck on a rather early speedbump.The project involves creating 10 arrays of randomly generated integers (from 0 to 99), where each array has a different number of elements (n). After we have several pools of ints to work with, I need to enact different sorting algorithms on said arrays - but I haven't even made it that far yet.
I've successfully made a for-loop generate an array where each int is random. The loop then restarts with a new value for 'n', and generates another array of random integers.
My code is as follows:
import java.util.Arrays;
public class Testing {
public static void arrayGenerator() {
int[] elements = { 100, 250, 500, 750, 1000, 1250, 2500, 3750, 5000, 6250 }; // 10 different values for 'n' to work with.
int n; // Number of elements per array.
int i; // Index of n, ie. 0 = 100, 1 = 250, 2 = 500, etc.
int k; // Index of element in generated array.
//Generate a separate array of random numbers for each value of 'n'.
for (i = 0; i < elements.length; i++) {
n = elements[i];
int[] sortableArray = new int[n];
//Populate each array with random numbers ranging from 0 to 99.
for (k = 0; k < n; k++) {
sortableArray[k] = (int) (Math.random() * 100);
}
System.out.println(Arrays.toString(sortableArray));
}
}
public static void main(String[] args) {
Testing arrGen = new Testing();
arrGen.arrayGenerator();
}
}
The 'System.out.println(Arrays.toString(sortableArray))' was just to see if the numbers were generating (and the correct amount of numbers was generating).Here's where I've ground to a halt. If I understand correctly, each subsequent array is overwriting the previous one - so by the end I don't have 10 arrays, I have one, where n = 5000.
I've looked into using a 2D array, an ArrayList, or a Map, but my efforts were in vain (ie., I'm not too sure how to go about that).When I tried to form a 2D array, in which I'd try to use "(int) (Math.random() * 100)" to set the value for [k], I'd consistently get NullPointExceptionErrors. Which means I was doing something incorrectly, but I'm not sure what.
Later in my project, I need to be able to take all these arrays, sort them (individually), take note of the time taken to sort them... etc. But for now I'm having trouble storing them in the first place.
I'm sure the solution is quite simple, but I've just been stumped for the last while, and I can't seem to reach the solution. If anyone could guide me towards an optimal solution, I'd really appreciate it!
Thanks for reading!
EDIT - For extra clarity, here was my feeble attempt at using a 2D array (replacing both for-loops from the code above):
for (i = 0; i < elements.length; i++) {
n = elements[i];
//Populate each array with random numbers ranging from 0 to 99.
for (k = 0; k < n; k++) {
int[][] sortableArray = new int[i][n];
sortableArray[i][k] = (int) (Math.random() * 100);
However, this was the result:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at ie.gmit.dip.Testing.arrayGenerator(Testing.java:22)
at ie.gmit.dip.Testing.main(Testing.java:32)
Where the error directs to this line:
sortableArray[i][k] = (int) (Math.random() * 100);
I'm stumped. Any and all insight is greatly appreciated!
Thanks.
Just store your array in a list before the end of the for-loop:
import java.util.Arrays;
public class Testing {
public static void arrayGenerator() {
int[] elements = { 100, 250, 500, 750, 1000, 1250, 2500, 3750, 5000, 6250 }; // 10 different values for 'n' to work with.
int n; // Number of elements per array.
int i; // Index of n, ie. 0 = 100, 1 = 250, 2 = 500, etc.
int k; // Index of element in generated array.
//Create a list to store all your arrays
LinkedList<int[]> listOfArrays = new LinkedList<int[]>();
//Generate a separate array of random numbers for each value of 'n'.
for (i = 0; i < elements.length; i++) {
n = elements[i];
int[] sortableArray = new int[n];
//Populate each array with random numbers ranging from 0 to 99.
for (k = 0; k < n; k++) {
sortableArray[k] = (int) (Math.random() * 100);
}
listOfArrays.add(sortableArray);
System.out.println(Arrays.toString(sortableArray));
}
}
public static void main(String[] args) {
Testing arrGen = new Testing();
arrGen.arrayGenerator();
}
}

Integers in array Java

I have an array that contains [45,8,50,15,65,109,2]. i would like to check to see if the zero element of my array is greater than my first element.
if ( 45 > 8)
then i would like to add 45 to brand new sub array.
i would like to continue checking my array for anything that is bigger than 45 and add it to the new sub array.
The new sub array has to keep the numbers added in the way they where added.The result should be [45,50,65,109]
I thought by creating this was going in the right direction but im doing something wrong so please help.
int[] x = [45,8,50,15,65,109,2];
int[] sub = null;
for(int i = 0; i > x.length; i++) {
for(int k = 0; k > x.length; k++) {
if(x[i] > x[k]){
sub = i;
First thing first. Your question contains some errors.
you should write int[] x = {45,8,50,15,65,109,2}; instead of int[] x = [45,8,50,15,65,109,2]; You can not use [] to initialize array!
What does it mean for(int i = 0; i > x.length; i++). Your program must not run! Because, the value of i is less than x.langth. First condition check is false, so loop will not works!
Same for for(int k = 0; k > x.length; k++)
How do you want to store value in an array without index? You have to write sub[i] = x[i]; here, i means what index value you want to store where!
Finally, do you want to do sorting? If yes, then you need another variable named temp means temporary!
Try to clear the basic and after then try this code.Sorting Link
Best of Luck!
It is possible to filter the input array using Java 8 Stream API:
int[] x = {45, 8, 50, 15, 65, 109, 2};
int[] sub = Arrays.stream(x)
.filter(n -> n >= x[0])
.toArray();
System.out.println(Arrays.toString(sub));
Output:
[45, 50, 65, 109]
If you're trying to fetch everything greater than 0th element.
Use the following:
Plain old java code:
int[] x = {45,8,50,15,65,109,2};
int[] sub = new int[x.length];
int first = x[0];
sub[0]=first;
int index=1;
for(int i = 1; i < x.length; i++) {
if(x[i] > first){
sub[index]=x[i];
index++;
}}
Streams API:
int[] x = {45, 8, 50, 15, 65, 109, 2};
int[] sub = Arrays.stream(x).filter(number -> number>=
x[0]).toArray();
where stream() is converting array to a stream, filter is applying the required condition and then ending it with conversion into an Array again.

Duplicate array in java and need to print rest of array element

Please look in to the below code. It print the only duplicate elements in array. I need to print also rest of array element, please try to help me.
public class DuplicateArray {
public static void main(String args[]) {
int array[] = { 10, 20, 30, 20, 40, 40, 50, 60, 70, 80 };// array of ten elements
int size = array.length;
System.out.println("Size before deletion: " + size);
for (int i = 0; i < size; i++) {
for (int j = i + 1; j < size; j++) {
if ((array[i]== array[j])) { // checking one element with all the element
System.out.println(array[i]);
}
}
}
Ouput:
20
40
Here I need to print the rest of array element ?
In Java 8, you can easily remove duplicates from an integer array using IntStream.
int[] noDuplicates = IntStream.of(array).distinct().toArray();
To print them instead of putting them in an array, use
IntStream.of(array).distinct().forEach(System.out::println);
You can use Set to solve this.
List<Integer> list = Arrays.asList(ArrayUtils.toObject(array));
Set<Integer> set = new HashSet<Integer>(list);
List<Integer> withoutDuplicates = new ArrayList<Integer>(set);
int[] newArrayWithoutDuplicates = ArrayUtils.toPrimitive(withoutDuplicates.toArray(new int[withoutDuplicates.size()]));
Finally, you have the array without duplicates.
Your question as to what you want to do isn't very clear but what I think is you want is to print the array elements without repetition.
If this is indeed the case, the following code will do it.(The explanation of the code is given after the output)
public class DuplicateArray {
public static void main(String args[]) {
int array[] = { 10, 20, 30, 20, 40, 40, 50, 60, 70, 80 };// array of ten elements
int size = array.length;
System.out.println("Size before deletion: " + size);
boolean duplicateElement=false;//this becomes true if there is a duplicate element in the array before the occurrence of this element
for (int i = 0; i < size; i++, duplicateElement=false) {
for (int j = 0; j < i; j++) {
if ((array[i]== array[j])) { // checking one element with all the elements
duplicateElement=true; //Duplicate element found in array
break;
}
}
if(!duplicateElement)
System.out.println(array[i]);
}
}
}
Output:
10
20
30
40
50
60
70
80
Now, the idea in this code is instead of starting the inner loop from i+1 and going till array.size, start it from 0 and go till i. duplicateElement is a flag variable the value of which becomes true if a duplicate element of array[i] is present in the array at position < i. However, when it's the first occurrence of the duplicate element, there is no other same element before array[i], only after. Hence the repetitive elements are also printed just once

Dealing with overlapping numbers in an array

My program takes a pair of numbers and subtracts them from one another then adds all the differences from the pairs back up for a total.
My problem is that some of the numbers overlap, by numbers I am using start and end times. I need to find a way to disregard overlapping numbers so that an input of
{{10, 14}, {4, 18}, {19, 20}, {19, 20}, {13, 20}
returns a total of 16 and not 27. Thus far I have created another array called hours to check off times already existing. Here is that portion of code:
public static int monitoring(int[][] intervals) {
int sum = 0;
int start = 0;
int end = 0;
boolean[] hours = new boolean[24];
int count = 0;
for(int i = 0; i < intervals.length; i++) {
end = intervals[i][1];
start = intervals[i][0];
for(int j = start; j < end; j++) {
hours[j] = true;
count++;
sum += end - start;
}
}
return sum;
I do not know what you are reaaly trying to get, 2 options possible:
you are probably trying to get difference between maximum of the
2nd element if pairs, and minimum of the 1st element in pairs
you want to count numbers of unique "points" (or hours) in given
interval list.
Simplest solution can be:
if (!hours[j]) {
hours[j] = true;
count++;
}
In this case you do not even need "sum" variable.

Moving every element down one in an array (Java)

I've had a decent search and am unable to find working code that moves down an array. What I am hoping to do, is to store the value in the last position in the array, replace the last position and then move array[20] to array[19]. This is meant to count the last 20 moves the player makes, but I'm having trouble actually storing. This is what I have attempted to do
//an int moveArray[20] previously stated and instantiated
int temp1, temp2;
for (int i = moveArray.length - 1; i > 0; i--)
{
temp1 = moveArray[i - 1];
temp2 = moveArray[i - 2];
moveArray[i - 1] = moveArray[i];
temp1 = temp2;
}
moveArray[moveArray.length - 1] = intoWalk;
any advice or solutions would really help, thanks
From what I understand of your code . You should use the following loop, there seems to be no need for temporary variables.
for(int i=0;i<moveArray.length-1;i++){
moveArray[i] = moveArray[i+1];
}
moveArray[moveArray.length - 1] = intoWalk;
First, you don't need to use temporary variables :
int [] moveArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
int intoWalk = 21;
for (int i = 0; i < moveArray.length-1; i++) {
moveArray[i] = moveArray[i+1];
}
moveArray[moveArray.length - 1] = intoWalk;
for (int i=0; i<moveArray.length; i++)
System.out.println(moveArray[i]);
But there is a better way to do it : use a linked list to emulate a FIFO :
LinkedList<Integer> fifo = new LinkedList<Integer>();
int intoWalk = 21;
for (int i=1; i<=20; i++)
fifo.add(i);
fifo.removeFirst();
fifo.add(intoWalk);
for (Integer fifoItem : fifo)
System.out.println(fifoItem);
By doing this, you don't have to modify every element in your array each time you want to add a number, just to add and remove an item from the linked list.
//an int moveArray[20] previously stated and instantiated
int temp1, temp2;
temp1 = moveArray[moveArray.length - 1];
for (int i = moveArray.length - 2; i >= 0; i--)
{
temp2 = moveArray[i];
moveArray[i] = temp1;
temp1 = temp2;
}
moveArray[moveArray.length - 1] = intoWalk;
The above should do what you want.
However, I don't think this is the right way to go.
I would use the same array as a circular array - that way - you don't need to move down everytime.
Maintain a start index. It begins at
start = 0;
It remains at 0 till the time all 20 elements are filled up.
When the next element comes in,
moveArray[start] = intoWalk;
++start;
When you want to iterate through the array at any time, you begin at start instead of beginning at 0.
int i = start;
do
{
// do what you want
i = (i + 1)%20;
} while (i != start);
First make the last element free by moving all the elements one row down.
Sample :
String[] sarr=new String[10];
for(int i=0;i<sarr.length;i++){
sarr[i]=sarr[i+1];
}
Then assign the new variable to the end.
sarr[sarr.length-1]="new value";
This approach is simpler and more readable.
EDIT : Yes Bohemian is right it was throwing an ArrayIndexOutOfBounds exception. The reason was that i+1 will try to refer to an index out of the array's range at the last iteration.
The solution is either to set the last element to null or break when it's the last element.
I will go with setting the last element to null. The changed code is below.
int nextElementIndex = i + 1;
sarr[i] = nextElementIndex < sarr.length ? sarr[nextElementIndex] : null;

Categories