I need help with this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 54
at Main.oddSort(Main.java:44)
at Main.main(Main.java:19)
I understand that this error occurs because I am trying either trying to assign too many values in the array correct? I just don't know how to fix it or why what I did was wrong.
The assignment is to generate 100 random numbers, and to call two different functions, one after the other to assign the odd and even numbers into two different arrays and to display them.
Here is the section that is giving me trouble:
public static int[] oddSort ( int input[] )
{
int amountOfOdd = 0;
int j = 0;
for(int i = 0; i < input.length; i++)
{
if (input[i] % 2 != 0)
amountOfOdd++;
}
int[] odd = new int[amountOfOdd];
for(int i = 0; i <= 99; i++)
{
if (input[i] % 2 != 0)
/*it's this line specifically that doesn't work, according to the debugger*/
odd[j] = input[i];
j++;
}
return odd;
}
Here is the full thing:
public class Main
{
public static void main(String[] args)
{
int[] numbers = new int[100];
for(int i = 0; i < numbers.length-1; i++)
numbers[i] = (int)(Math.random() * 26);
int[] odd = oddSort(numbers);
int[] even= evenSort(numbers);
System.out.println("The odd numbers are:");
display( odd );
System.out.println("The even number are:");
display( even );
}
public static int[] oddSort ( int input[] )
{
int amountOfOdd = 0;
int j = 0;
for(int i = 0; i < input.length; i++)
{
if (input[i] % 2 != 0)
amountOfOdd++;
}
int[] odd = new int[amountOfOdd];
for(int i = 0; i <= 99; i++)
{
if (input[i] % 2 != 0)
odd[j] = input[i];
j++;
}
return odd;
}
public static int[] evenSort ( int input[] )
{
int amountOfEven = 0;
int j = 0;
for(int i = 0; i < input.length; i++)
{
if (input[i] % 2 != 0)
amountOfEven++;
}
int[] even = new int[amountOfEven];
for(int i = 0; i < input.length; i++)
{
if (input[i] % 2 != 0)
even[j] = input[i];
j++;
}
return even;
}
public static void display (int input[] )
{
for (int i = 0; i < input.length; i++)
System.out.print(input[i] + " ");
}
}
The cause of the exception is the fact that you did not put the brackets around the body of your if condition. Should be like this :
for(int i = 0; i <= 99; i++)
{
if (input[i] % 2 != 0){
odd[j] = input[i];
j++;
}
}
Right now, what you are actually doing is increasing j every time through the loop, not every time there is an odd number. So of course you will get this exception when at least one value in the input is not odd since the odd array will have a size that is less than the size of input.
Related
Trying to write a program that asks the a user for 10 integers as input. The program
places the even integers into an array called evenList, the odd integers into
an array called oddList, and the negative numbers into an array called
negativeList. The program displays the contents of the three arrays after
all of the integers have been entered.
This is my code:
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int countNeg = 0;
int countOdd = 0;
int countEven = 0;
int[] list = new int[10];
System.out.println("Please enter 10 integers:");
for(int i = 0; i < list.length; i++)
{
list[i] = scan.nextInt();
if(list[i] < 0)
{
countNeg++;
}
if(list[i] % 2 == 0 && list[i] > 0)
{
countEven++;
}
if(list[i] % 2 == 1 && list[i] > 0)
{
countOdd++;
}
}
int[] oddList = new int[countOdd];
int[] evenList = new int[countEven];
int[] negativeList = new int[countNeg];
for(int i = 0; i < list.length; i++)
{
if(list[i] < 0)
{
for(int j = 0; j < countNeg; j++)
{
negativeList[j] = list[i];
}
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 0 && list[i] > 0)
{
for(int j = 0; j < countEven; j++)
{
evenList[j] = list[i];
}
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 1 && list[i] > 0)
{
for(int j = 0; j < countOdd; j++)
{
oddList[j] = list[i];
}
}
}
for (int i : negativeList)
{
System.out.print(i + " ");
}
System.out.println();
for (int i : evenList)
{
System.out.print(i + " ");
}
System.out.println();
for (int i : oddList)
{
System.out.print(i + " ");
}
}
}
The program prints the Arrays with the correct amount of values but the wrong numbers. It prints only the last negative, even, or odd number to be input. ex input is 1, 2, 3, 4, 5, 6, -1, -2, -3, -4. For negativeList it prints -4 -4 -4 -4. Im guessing something is wrong in the loops after the arrays are created. Please help!!
you can very much simplify your code with using ArrayList instead of array. For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int length = 10;
System.out.println("Please enter 10 integers:");
List<Integer> oddList = new ArrayList<>();
List<Integer> evenList = new ArrayList<>();
List<Integer> negativeList = new ArrayList<>();
for (int i = 0; i < length; i++) {
int n = scan.nextInt();
if (n < 0) {
negativeList.add(n);
} else if (n % 2 == 0) {
evenList.add(n);
} else {
oddList.add(n);
}
}
for (int i : negativeList) {
System.out.print(i + " ");
}
System.out.println();
for (int i : evenList) {
System.out.print(i + " ");
}
System.out.println();
for (int i : oddList) {
System.out.print(i + " ");
}
}
there are a few issues with the code you provided.
First, in the for loops that initialize the negativeList, evenList, and oddList arrays, you are overwriting the values at each iteration. This means that the final arrays will only contain the last value that was assigned to them. To fix this, you can use a counter variable to keep track of the next index to be filled in each array, like this:
int negCounter = 0;
int evenCounter = 0;
int oddCounter = 0;
for(int i = 0; i < list.length; i++)
{
if(list[i] < 0)
{
negativeList[negCounter] = list[i];
negCounter++;
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 0 && list[i] > 0)
{
evenList[evenCounter] = list[i];
evenCounter++;
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 1 && list[i] > 0)
{
oddList[oddCounter] = list[i];
oddCounter++;
}
}
Second, you are not checking if the input values are integers. If the user enters a non-integer value, the program will throw an exception. You can add a check to make sure that the input is an integer like this:
if(scan.hasNextInt())
{
list[i] = scan.nextInt();
// ... rest of the code
}
else
{
System.out.println("Please enter an integer.");
// If the input is not an integer, discard it and move to the next
input
scan.next();
}
I have a factorial function on my program that works fine until i try to execute the function deleteRepeated(), the console is telling me that the error is in the return of the factorial function, maybe it's being called by a single function too many times in a short period of time? I've been stuck for hours.
import java.util.Scanner;
public class ex9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int[] newArr = new int[n - repeated(arr)];
int[] finalArr = deleteRepeated(arr, newArr);
for (int a : finalArr) {
System.out.println(a);
}
}
public static long factorial(int n) {
if (n == 0)
return 1;
return (n * factorial(n - 1));
}
public static int repeated(int arr[]) {
int n = arr.length;
int mix = (int) (factorial(n) / (2 * factorial(n - 2)));
int i = 0;
int k = 0;
int rep = 0;
int a = -100;
while (i < mix) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != j) {
a = j;
rep += 1;
}
i++;
}
k++;
}
return rep;
}
public static int[] deleteRepeated(int arr[], int newArr[]) {
int n = arr.length;
int rep = repeated(arr);
int i = 0;
int k = 0;
int a = -100;
while (i < newArr.length) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != arr[k]) {
a = arr[j];
newArr[k] = arr[k];
}
i++;
}
k++;
}
rep = repeated(newArr);
if (rep > 0) {
int[] newArr2 = new int[newArr.length - rep];
deleteRepeated(newArr, newArr2);
}
return newArr;
}
}
Only thing i could do to avoid the error was stopping the function from executing :/, maybe it has to do with how i'm re-calling it at the end of each execution...? is what i did allowed?
So, deleteRepeated is all messed up. The issue is deleteRepeated does not actually remove duplicate elements, so the check for the base case of recursion always fails. I'm not sure why you're using recursion here anyway; if the while loop worked properly, it could remove all duplicates without need for recursion.
It appears that you copy-pasted the implementation of repeated into deleteRepeated, and you replaced the logic for handling repeated elements with logic that handles non-repeated elements.
Here is how I would implement the method:
public static int deleteRepeated(int arr[], int newArr[]) {
int n = 0;
for(int i = 0; i < arr.length; i++) {
boolean unique = true;
for(int j = 0; j < n; j++)
unique = unique && newArr[j] != arr[i];
if(unique)
newArr[n++] = arr[i];
if(n >= newArr.length) break;
}
return n;
}
I'm practicing coding on HackerRank, and I have the following code, which gets a different outputs.
The task is the following:
Given an array of integers, find the longest subarray where the absolute difference between any two elements is less than or equal to.
Example:
a = [1,1,2,2,4,4,5,5,5];
There are two subarrays meeting the criterion: [1,1,2,2] and [4,4,5,5,5]. The maximum length subarray has 5 elements.
The following code gets the desired output:
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max)
max = counter;
counter = 0;
}
return max+1;
}
While this one, gets a different output -
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max){
max = counter;
counter = 0;
}
}
return max+1;
}
As you can see, the difference between the 2 codes are just the brackets after the if(counter > max) part. In the latter case, the counter is always 1 unit more than it should be.
Can anyone please explain it to me, why the code behaves different in this case?
It's because in the first snippet counter = 0; is not in the if block.
When if is not enclosed in brackets, it only evaluates the first instruction after it, so the counter = 0; is always executed.
Here's an example with better indentation:
public static int pickingNumbers(List<Integer> a)
{
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++)
{
for(int j = i+1; j< a.size(); j++)
{
if(Math.abs(a.get(i)-a.get(j)) <= 1)
{
counter++;
}
}
if(counter > max)
max = counter;
counter = 0; // Not in the if statement, so the counter is always reset!
}
return max+1;
}
const genObj = (ar) => {
let obj = {}
for(let i of ar) {
!(obj[i])? obj[i] = 1 : obj[i]++
}
return obj
}
function pickingNumbers(a) {
// Write your code here
let obj = genObj(a)
let k = Object.keys(genObj(a))
let i = 0
let max = 0
while (i <= k.length - 1) {
for(let j = i; j <= k.length - 1; j++){
if(i === j) continue
if(Math.abs(k[i] - k[j]) <= 1) {
if(obj[k[i]] + obj[k[j]] > max)
max = obj[k[i]] + obj[k[j]]
}
}
i++
}
return max > Math.max(...Object.values(obj)) ? max : Math.max(...Object.values(obj))
}
problem statement: I have to remove n duplicates from array.
Here is the full problem statement : https://pastebin.com/EJgKUGe3
and my solution is :
public class minion_labour_shift_2ndTry {
static int[] data = {1,2, 2, 3, 3, 3, 4, 5, 5};
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
data = answer(data, n);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
public static int[] answer(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
int[] result = new int[99];
ArrayList<Integer> temp = new ArrayList<>();
int counter = 0, count ,maxCount = 0;
for (int i = 0; i < data.length; i++) {
boolean isDistinct = false;
for (int j = 0; j < i; j++) {
if (data[i] == data[j]) {
isDistinct = true;
break;
}
}
if (!isDistinct) {
result[counter++] = data[i];
}
}
for (int i = 0; i < counter; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (result[i] == data[j]) {
count++;
}
}
System.out.println("....... count"+count);
if (maxCount <= count){
maxCount = count;
}
if (count <= n){
temp.add(result[i]);
}
}
if (maxCount-1 < n){
return data;
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
}
Now, my question is, what I am missing and what should I do to pass all the 10 cases.
Thanks In Advance :)
NB:It will be compiled in java 7 , and Map,hashset or third-party libraries, input/output operations, spawning threads or processes and changes to the execution environment are not allowed.
I misread the requirements initially, this does what is asked:
public static int[] answer(int[] data, int n) {
Map<Integer, Integer> counts = new HashMap<>();
int elementsNeeded = 0;
for (int i = 0; i < data.length; i++) {
Integer currentCount = counts.get(data[i]);
currentCount = currentCount == null ? 1 : ++currentCount;
counts.put(data[i], currentCount);
if (currentCount <= n + 1) {
elementsNeeded += currentCount > n ? -n : 1;
}
}
int[] resultArray = new int[elementsNeeded];
int j = 0;
for (int i = 0; i < data.length; i++) {
if (counts.get(data[i]) <= n) {
resultArray[j++] = data[i];
}
}
return resultArray;
}
...and also your own code, slightly altered:
public static int[] answer2(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
ArrayList<Integer> temp = new ArrayList<>();
int count;
for (int i = 0; i < data.length; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (data[i] == data[j]) {
count++;
}
}
if (count <= n){
temp.add(data[i]);
}
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
Not going to provide a full solution but suggesting a reworking of the algorithm because it's not clear what you're doing, you never explained your actual thoughts of the algorithm. For example, what are you using isDistinct for?
1) Loop through once and compute the frequency of every number. You can just use an array of length 100 since that's all the data inputs will be. As you loop through, keep track of two things: The total number of entries that occur more than n times, as well as which those numbers are
2) Create a resulting array of the appropriate size (calculated from above) and loop through the list again and fill in the elements that didn't cross the threshold.
When population oddList, evenList and negativeList from the inputList the program only populates it with one int instead of all corresponding ints from the inputList array. The output should be a list from each array whose numbers correspond to its title. The numbers are input by user into inputList array and then from there it determines whether it is odd, even, and negative and then fills the corresponding arrays.
I.E. evenList is filled with even ints from inputList.
public class ProjectTenOne
{
public static void main(String[] args)
{
int[] inputList = new int[10];
int[] oddList = null;
int[] evenList = null;
int[] negativeList = null;
int evenCount = 0;
int oddCount = 0;
int negCount = 0;
Scanner input = new Scanner(System.in);
//System.out.println("Enter any ten integers: ");
for(int list = 0; list < inputList.length; list++)
{
System.out.println("Enter any " + (inputList.length - list) + " integers: ");
inputList[list] = input.nextInt();
}
System.out.println();
System.out.println("The numbers you entered: ");
for(int in = 0; in < inputList.length; in++)
{
System.out.println(inputList[in]);
}
for(int ls = 0; ls< inputList.length; ls++)
{
if(inputList[ls] % 2 == 0)
{
evenCount = evenCount +1;
}
if(inputList[ls] % 2 != 0)
{
oddCount = oddCount +1;
}
if(inputList[ls] < 0)
{
negCount = negCount +1;
}
}
evenList = new int[evenCount];
oddList = new int[oddCount];
negativeList = new int[negCount];
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
for(int j = 0; j < evenList.length; j++)
{
evenList[j] = inputList[l];
}
}
if((inputList[l] % 2) != 0)
{
for(int k = 0; k < oddList.length; k++)
{
oddList[k] = inputList[l];
}
}
if(inputList[l] < 0)
{
for(int h = 0; h < negativeList.length; h++)
{
negativeList[h] = inputList[l];
}
}
}
System.out.println("The ODD List is: ");
for(int i = 0; i < oddList.length; i++)
{
System.out.println(oddList[i]);
}
System.out.println("The EVEN List is: ");
for(int j = 0; j < evenList.length; j++)
{
System.out.println(evenList[j]);
}
System.out.println("The NEGATIVE List is: ");
for(int k = 0; k < oddList.length; k++)
{
System.out.println(negativeList[k]);
}
}
}
I'll take evenList as the example here, but the same applies to the other two arrays as well.
In your code, you iterate over your inputList and check for an even number. If it is even, you set the entire evenList array to the found value, instead of just a single element.
You can solve this problem by declaring an int outside of your outer loop that keeps track of the number of even numbers entered. As an example:
int evenIndex = 0;
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
evenList[evenIndex++] = inputList[l];
}
/*Other code*/
}
You also made a mistake in your last loop. You iterate over negativeList, but you use the size of evenList. This will result in an ArrayIndexOutOfBoundsException when negativeList is smaller than evenList.