This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 1 year ago.
I want to sort this array = {20, 46, 22, 19, 6, 42, 14, 5, 48, 47, 17, 39, 51, 7, 2} using bucket sort. I get a arrayindexoutofboundsexception error in my code. Can someone please help me to correct my code...
package com.bucketsort;
import java.util.*;
public class Main {
public static void main(String[] args) {
int[] arr = {20, 46, 22, 19, 6, 42, 14, 5, 48, 47, 17, 39, 51, 7, 2};
System.out.println("Unsorted: " + Arrays.toString(arr));
bucketSort(arr);
System.out.println("Sorted : " + Arrays.toString(arr));
}
public static int[] bucketSort(int[] arr) {
int max = getMax(arr);
int[] sortedArray = new int[max + 1];
//loop and place n at nth position
for (int cur : arr) {
for (int i = 0; i <= max; i++) {
int currentVal = arr[i];
sortedArray[currentVal] = currentVal;
}
}
return sortedArray;
}
//method to get the maximum value
public static int getMax(int[] arr) {
int maxValue = arr[0];
for(int i=1;i<arr.length;i++) {
if(arr[i] > maxValue) {
maxValue = arr[i];
}
}
return maxValue;
}
}
This is a screenshot of what I get when i run this code.
The problem starts here:
for (int i = 0; i <= max; i++) {
int currentVal = arr[i];
sortedArray[currentVal] = currentVal;
}
Since you are returning the value from the getMax function instead of index.
The problem here is this part of your code, you loop from the 0 to max for the arr which its length fixed 15 and before the max
for (int cur : arr) {
for (int i = 0; i <= max; i++) { <---
int currentVal = arr[i]; <---
sortedArray[currentVal] = currentVal;
}
}
, Just remove that and use the following:
for (int cur : arr) {
sortedArray[curr] = curr;
}
Related
This is a perceptual question.
I want to know why there is an interference with these two independent methods.
I know both are reading the same array (my_array)
independently every response of the methods is correct. But when I turn on both of them (min and max methods), the response of the below method is wrong.
This is my code:
public class myPractice {
public static int max(int[] my_array1) {
int i = 0;
int max = my_array1[i];
for(i = 0; i < my_array1.length-1; i++) {
if(my_array1[i] > my_array1[i+1]) {
my_array1[i+1] = my_array1[i];
max = my_array1[i];
}else {
max = my_array1[i+1];
}
}
System.out.println("Max= " +max);
return max;
}
public static int min(int[] my_array2) {
int j = 0;
int min = my_array2[j];
for(j = 0; j < my_array2.length-1; j++) {
if(my_array2[j] < my_array2[j+1]) {
my_array2[j+1] = my_array2[j];
min = my_array2[j];
}else {
min = my_array2[j+1];
}
}
System.out.println("Min= " +min);
return min;
}
public static void main(String args[]) {
int[] my_array = {25, 14, 56, 5, 36, 89, 77, 18, 29, 49};
max(my_array);
min(my_array);
}
}
The issue is that you are altering the input array in the min and max methods:
my_array1[i+1] = my_array1[i];
As a result, in the next call, you are manipulating an array different from the initial one. As a matter of fact, in your script, max(my_array) sets my_array equals to [25, 25, 56, 56, 56, 89, 89, 89, 89, 89].
You can simplify min and max as the following ones:
public static int max(int[] myArr) {
int max = myArr[0];
for (int i = 1; i < myArr.length; i++){
if (myArr[i] > max)
max = myArr[i];
}
return max;
}
public static int min(int[] myArr) {
int min = myArr[0];
for (int i = 1; i < myArr.length; i++){
if (myArr[i] < min)
min = myArr[i];
}
return min;
}
Furthermore, I want to recommend some best practices:
use the camel case when programming in java. Write myArray instead of my_array;
print the result of a method in the main:
public static void main(String[] args) {
int[] myArray = {25, 14, 56, 5, 36, 89, 77, 18, 29, 49};
System.out.println("Max = " + max(myArray));
System.out.println("Min = " + min(myArray));
}
I'm trying to swap the maximum and minimum values in an array in my program.
Here is the code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int myArray[] = new int[25];
for (int i = 0; i < myArray.length; i++) {
System.out.println("Enter a number: ");
myArray[i] = in.nextInt();
}
int maximum = maxNumber(myArray);
int minimum = minNumber(myArray);
System.out.println(Arrays.toString(myArray));
}
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
//finds the maximum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
maximumValue = arr[a];
}
}
return maximumValue;
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
//finds the minimum value in an array
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
minimumValue = arr[a];
}
}
return minimumValue;
}
I have two separate functions to find the Maximum and Minimum values, but I'm stuck on the actual swapping of the values. The two functions work as I've used them for another program, but I'm not sure if they would work for this program.
At first I was thinking of finding them by setting them equal to each other in some way, but that led to nothing.
Any help would be appreciated.
public static void main(String... args) {
Scanner scan = new Scanner(System.in);
int[] arr = new int[25];
System.out.format("Enter array int numbers (%d in total): ", arr.length);
for (int i = 0; i < arr.length; i++)
arr[i] = scan.nextInt();
System.out.println(Arrays.toString(arr));
swamMinMax(arr);
System.out.println(Arrays.toString(arr));
}
private static void swamMinMax(int[] arr) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
min = Math.min(min, arr[i]);
max = Math.max(max, arr[i]);
}
for (int i = 0; i < arr.length; i++) {
if (arr[i] == min)
arr[i] = max;
else if (arr[i] == max)
arr[i] = min;
}
}
Output:
Enter array int numbers (25 in total): 1 2 3 4 5 6 7 8 9 10 -1 -1 -1 14 15 16 17 18 19 20 21 22 23 66 66
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, 66, 66]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 66, 66, 66, 1, 1, 1, 17, 18, 19, 20, 21, 22, 23, -1, -1]
You were real close. I copied some of the code and commented where the changes need to be made. You can still use your existing code to populate the array from the console.
Also, kudos for assigning the first element in the array to min or max and starting your loop at 1. A lot of folks don't think about doing that.
int myArray[] = {1,10,-5,99,48,-22,43, 44,100,2};
System.out.println(Arrays.toString(myArray)); // print original array
int maxIdx = maxNumber(myArray); // get index of max
int minIdx = minNumber(myArray); // get index of min
// now swap max and min using the returned indices.
int save = myArray[maxIdx];
myArray[maxIdx] = myArray[minIdx];
myArray[minIdx] = save;
System.out.println(Arrays.toString(myArray)); // print the altered array
public static int maxNumber(int[] arr) {
int maximumValue = arr[0];
// finds the maximum value in an array
int idx = 0; //idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] > maximumValue) {
idx = a; //save index of current max
maximumValue = arr[a];
}
}
return idx; // return index of max
}
public static int minNumber(int[] arr) {
int minimumValue = arr[0];
// finds the minimum value in an array
int idx = 0; // idx = 0 to start
for (int a = 1; a < arr.length; a++) {
if (arr[a] < minimumValue) {
idx = a; // save index of current min
minimumValue = arr[a];
}
}
return idx; // return index of min
}
This would print
[1, 10, -5, 99, 48, -22, 43, 44, 100, 2]
[1, 10, -5, 99, 48, 100, 43, 44, -22, 2]
You can use IntStream to find indexes of the maximum and minimum elements and then swap their values:
int[] arr = {1, 3, 5, 6, 4, 2, 8, 7, 9, -1, -3};
// indexes of the maximum and minimum elements
int max = IntStream.range(0, arr.length)
.boxed().max(Comparator.comparing(i -> arr[i])).orElse(-1);
int min = IntStream.range(0, arr.length)
.boxed().min(Comparator.comparing(i -> arr[i])).orElse(-1);
// swap the values
int temp = arr[max];
arr[max] = arr[min];
arr[min] = temp;
System.out.println(Arrays.toString(arr));
// [1, 3, 5, 6, 4, 2, 8, 7, -3, -1, 9]
This question already has answers here:
Creating a random array of type int. Java
(3 answers)
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 1 year ago.
I am just looking to change my code so that a random array of a fixed length of 100 integers is generated every time the code is ran rather than just have a pre-set array within the code. I am quite new to this so just need a guide in the right direction, thanks
public class Selectionsort {
public static void main(String[] args) {
int[] numbers = {15, 8, 6, 21, 3, 54, 6, 876, 56, 12, 1, 4, 9};
sort(numbers);
printArray(numbers);
}
public static int[] sort(int[] A) {
for (int i = 0; i < A.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < A.length; j++) {
if (A[j] < A[minIndex]) {
minIndex = j;
}
}
int temp = A[minIndex];
A[minIndex] = A[i];
A[i] = temp;
}
return A;
}
public static void printArray(int[] A) {
for (int i = 0; i < A.length; i++) {
System.out.println(A[i]);
}
}
}
public class Selectionsort {
public static void main(String[] args) {
int[] numbers = new int[100]
Random random = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = random.nextInt(100);
}
sort(numbers);
printArray(numbers);
}
}
The above snippet will help you to create a random numbers between 1 to 100 for the array of size 100.
You should look at the Random class.
More specifically:
nextInt() to fill it one by one
ints​(long) to get an IntStream of fixed size, which can be easily converted to an array with .toArray()
The below would fill an array of 100 integers with Random numbers from 1-1000
int[] numbers = new int[100];
Random rand = new Random();
for (int i = 0; i < numbers.length; i++) {
numbers[i] = rand.nextInt(1000);
}
However note that the above code might insert duplicates. If you want to avoid that, using a List in parallel to the array and checking whether the generated value already exists should ensure uniqueness :
int[] numbers = new int[100];
List<Integer> numbersList = new ArrayList<Integer>(numbers.length);
Random rand = new Random();
for (int i = 0; i < numbers.length; i++) {
int j = rand.nextInt(1000);
while (numbersList.contains(j)) {
j = rand.nextInt(1000);
}
numbers[i] = j;
numbersList.add(j);
}
Even though I think it would be wiser to get rid of the array and use just the List...
You can use Math.random method. This code generates an array of 10 random numbers in the range [50,60] inclusive.
int length = 10, min = 50, max = 60;
int[] arr = IntStream.range(0, length)
.map(i -> (int) (min + Math.random() * (max - min + 1)))
.toArray();
System.out.println(Arrays.toString(arr));
// [54, 51, 58, 59, 57, 56, 56, 54, 54, 58]
Full set of 11 random numbers:
Set<Integer> set = new HashSet<>();
while (set.size() < max - min + 1) {
set.add((int) (min + Math.random() * (max - min + 1)));
}
System.out.println(set);
// [50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]
How can I make this code not have any repeating numbers in it?
All I would like to do is make it so that it doesn't output any duplicates
in this little block.
int[] arr = {5,10,44,2, 44,44,5,10,44,2, 44,44};
int startScan;
int index;
int minindex;
int minValue;
for (startScan=0;startScan<(arr.length-1);startScan++){
minindex=startScan;
minValue =arr[startScan];
for (index=startScan+1; index<arr.length;index++){
if (arr[index]<minValue){
minValue=arr[index];
minindex=index;
}
}
arr[minindex]=arr[startScan];
arr[startScan]=minValue;
}
for(int x=0; x<arr.length;x++)
System.out.println(arr[x]);
Your code sorted the int array in ascending order. It would have been nice if you had mentioned that in your question, and not left it for someone else to spend time figuring out.
Removing the duplicates required some extra code.
Here is the results of a test run.
[2, 5, 10, 44]
Here's the revised version of your code. It's runnable, so you can copy the code and paste it into your IDE.
package com.ggl.testing;
import java.util.Arrays;
public class RemoveDuplicates {
public static void main(String[] args) {
int[] arr = { 5, 10, 44, 2, 44, 44, 5, 10, 44, 2, 44, 44 };
int masterIndex = 0;
for (int startScan = 0; startScan < (arr.length - 1); startScan++) {
int minindex = startScan;
int minValue = arr[startScan];
for (int index = startScan + 1; index < arr.length; index++) {
if (arr[index] < minValue) {
minValue = arr[index];
minindex = index;
}
}
arr[minindex] = arr[startScan];
arr[startScan] = minValue;
if (arr[masterIndex] < minValue) {
arr[++masterIndex] = minValue;
}
}
int[] newarr = Arrays.copyOf(arr, masterIndex + 1);
System.out.println(Arrays.toString(newarr));
}
}
This question already has answers here:
Random shuffling of an array
(31 answers)
Closed 8 years ago.
Try to shuffel 52 card of one deck with the random no.but this is returning same list as given. cardInDeck = 52;
public ArrayList<Card> cardShuffler() {
int newI;
Card temp,temp2,temp3;
Random randIndex = new Random();
for (int i = 0; i < cardsInDeck; i++) {
newI = randIndex.nextInt(cardsInDeck);
Log.i("Nulll", String.valueOf(newI));
temp = cards.get(i);
temp2= cards.get(newI);
//temp3 = temp;
//temp = temp2;
//temp2 = temp3;
cards.set(i, temp2);
cards.set(newI, temp);
}
return cards;
}
Consider using Collections.shuffle().
You can use it like this:
// assume `cards` is a `List`,
Collections.shuffle(cards);
// cards is now shuffled
For the curious, look over http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/Collections.java on line 514.
I think that the problem is not in the code you've provided. Try this (added logging and cards initialization) and it works:
private void tryToSuffle()
{
int newI;
Integer temp,temp2,temp3;
Random randIndex = new Random();
//initializing data.
Integer cardsInDeck = 52;
ArrayList<Integer> cards = new ArrayList<Integer>();
for (int i =0; i < cardsInDeck; i++) {
cards.add(i);
}
//....
//no change in the algorythm itself
for (int i = 0; i < cardsInDeck; i++) {
newI = randIndex.nextInt(cardsInDeck);
temp = cards.get(i);
temp2= cards.get(newI);
cards.set(i, temp2);
cards.set(newI, temp);
}
//printing the result.
for (int i =0; i < cardsInDeck; i++) {
System.out.println(cards.get(i));
}
}
So without changing the main algorythm it works as planned.
So probably what your not doing is assigning the returned value to the proper variable. Why inside this method your using some instance field cards? Couldn't you pass them as argument?
EDIT:
Just to support what I've writen above I made this test, and it works (without changes in the shuffling algorythm):
public class ShufflerTest {
private final Integer cardsInDeck = 52;
public static void main(String args[])
{
new ShufflerTest().run();
}
private void run() {
ArrayList<Integer> cards = new ArrayList<Integer>();
for (int i =0; i < cardsInDeck; i++) {
cards.add(i);
}
cards = tryToShuffle(cards);
//printing the result.
System.out.println(cards.toString());
}
private ArrayList<Integer> tryToShuffle(final ArrayList<Integer> cards)
{
int newI;
Integer temp,temp2;
Random randIndex = new Random();
ArrayList<Integer> shuffledCards = new ArrayList<Integer>();
shuffledCards.addAll(cards);
for (int i = 0; i < cardsInDeck; i++) {
newI = randIndex.nextInt(cardsInDeck);
temp = shuffledCards.get(i);
temp2= shuffledCards.get(newI);
shuffledCards.set(i, temp2);
shuffledCards.set(newI, temp);
}
return shuffledCards;
}
}
In the example I've added the shuffledCards array not to change the original cards array. This is good practice not to mess with the input param collection as you don't know if some other class uses it also. But if you decide not too use this additional shuffledCards variable it would work also.
My example output is (i've changed it to cards.toString() replacing the loop):
[46, 16, 23, 21, 28, 8, 37, 4, 47, 17, 9, 41, 51, 30, 20, 26, 10, 3, 2, 14, 29, 40, 25, 33, 34, 42, 15, 27, 32, 43, 39, 6, 22, 45, 31, 35, 48, 13, 5, 1, 12, 19, 49, 50, 44, 11, 7, 0, 18, 24, 38, 36]
You need this fix:
public ArrayList<Card> cardShuffler() {
int newI;
Card temp,temp2,temp3;
Random randIndex = new Random();
for (int i = 0; i < cardsInDeck; i++) {
newI = randIndex.nextInt(cardsInDeck - i) + i; // fixed here
Log.i("Nulll", String.valueOf(newI));
temp = cards.get(i);
temp2= cards.get(newI);
//temp3 = temp;
//temp = temp2;
//temp2 = temp3;
cards.set(i, temp2);
cards.set(newI, temp);
}
return cards;
}