This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I have two sorted arrays. I need to connect both of them into one new sorted array:
int[] arr1 = {1,2,3,6,8};
int[] arr2 = {4,5,9,12,208,234};
printArr(allSort(arr2,arr1));
}
public static int[] allSort(int[] arr, int[] arr3) {
int[] newArr = new int[arr.length + arr3.length];
int j = 0;
int k = 0;
for (int i = 0; i < newArr.length - 1; i++) {
if(j == arr3.length){
newArr[i] = arr[k];
k++;
}
if(k == arr.length){
newArr[i] = arr3[j];
j++;
}
if(arr[k] > arr3[j]){
newArr[i] = arr3[j];
j++;
} else if (arr[k] < arr3[j]) {
newArr[i] = arr[k];
k++;
}
}
return newArr;
}
I tried to build an array that has a length equal to the length of the both arrays summed together and then run a loop on it.
However, this code returns the error: AArrayIndexOutOfBoundsException: 5.
Just add continue in both the if condition like this,
if(j == arr3.length){
newArr[i] = arr[k];
k++;
continue;
}
if(k == arr.length){
newArr[i] = arr3[j];
j++;
continue;
}
So here anyway the other loop is completed thats why we are iterating and adding all the values so it doesn't need to check all other conditions so we can skip it.
Also,
for (int i = 0; **i < newArr.length**; i++)
Since you are checking "<".
The ArrayIndexOutOfBoundsException() is an Exception and what it basically means is that at some point you're trying to access a element of an array with an illegal index. Refer to the ArrayIndexOutOfBoundsException Documentation for more informations.
after looking to your code at some point here are the index's values:
.
In the loop you're calling arr[k] with k = 5 in if(arr[k] > arr3[j]) as arr is an Array of length 5 and thus has a maximum index of 4 and that is why you're getting an out of bounds exception.
Your main problem is control when first array finished.
I made some adjusts on your code and now it's working.
public static void main(String[] args) {
int[] arr1 = { 1, 2, 3, 6, 8 };
int[] arr2 = { 4, 5, 9, 12, 208, 234 };
int[] newArr = allSort(arr1, arr2);
for (int i = 0; i <= newArr.length - 1; i++) {
System.out.println(" " + newArr[i]);
}
}
public static int[] allSort(int[] arr1, int[] arr2) {
int j = 0;
int k = 0;
boolean endArr1 = false;
int[] newArr = new int[arr1.length + arr2.length];
for (int i = 0; i <= newArr.length - 1; i++) {
if (arr1[k] < arr2[j] && !endArr1) {
System.out.println("k: " + k + " " + arr1.length);
newArr[i] = arr1[k];
if(k < arr1.length-1)
k++;
else
endArr1 = true;
} else if (arr2[j] < arr1[k] || endArr1) {
System.out.println("j: " + j + " " + arr2.length);
newArr[i] = arr2[j];
if(j < arr2.length-1)
j++;
}
}
return newArr;
}
Related
Basically, I am trying to make an entirely new array of a new length that contains only the even ints in an array of integers.
However, I am getting an index out of bounds error. Can you help me find what I did wrong?
import java.util.Arrays;
public class findevens {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[]{4,8,19,3,5,6})));
}
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
//add even ints to new array
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[i] += arr[i];
}
}
return result;
}
}
You should use a new variable to keep track of the current result index (let's say, j):
public static int[] evens(int[] arr) {
int length = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
// Access result with `j` and update its value
result[j++] = arr[i];
}
}
return result;
}
Also, you can you streams:
int[] array = {1, 3, 4, 5, 6};
int[] even = IntStream.of(array).filter(item -> item%2 == 0).toArray();
System.out.println(Arrays.toString(even));
You need a new index variable for the result array and your assignment is also wrong as instead of assigning you are adding the even number to the result array element.
int j = 0;
int[] result = new int[length];
// add even ints to new array
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0)
{
result[j++] = arr[i];
}
}
Problem is you are using i for the result array AND the original array. You should only increment the result array inside of the IF (when you find an even number) otherwise, you go out of bounds due to i (the original arr) being a larger size than the result array.
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
//add even ints to new array
int resultCount = 0;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[resultCount] += arr[i];
resultCount++;
}
}
return result;
}
Simply when you want to assign a value to result[] you do it with the index in the array arr, 0, 1 and 5. You just have to declare an auxiliary int aux = 0; variable before second loop and increment according to arr[i] % 2 == 0 so true
result[i] += arr[i];
a
int aux = 0;
result[aux++] += arr[i];
Complete code
public class findevens {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[]{4,8,19,3,5,6})));
}
public static int[] evens(int[] arr) {
//create new array by determining length
//of even number ints
int length = 0;
int j = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
length++;
}
}
int[] result = new int[length];
int aux = 0;
//add even ints to new array
for (int i = 0; i < arr.length; i++){
if (arr[i] % 2 == 0) {
result[aux++] += arr[i];
}
}
return result;
}
}
Since you don't really know how long the resultant array will be you can copy them to the front of the current array. Then use the final location as the count of values.
int[] input = {1,2,3,4,5,6,7,8,9};
int k = 0;
for(int i = 0; i < input.length; i++) {
if (input[i] % 2 == 0) {
input[k++] = input[i];
}
}
int[] evens = Arrays.copyOf(input, k);
System.out.println(Arrays.toString(evens));
Prints
[2, 4, 6, 8]
A simple way is to filter even numbers using the Stream API and return the result as an array.
Arrays.stream(arr)
.filter(n -> n % 2 == 0)
.toArray();
Demo:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(evens(new int[] { 4, 8, 19, 3, 5, 6 })));
}
static int[] evens(int[] arr) {
return Arrays.stream(arr).filter(n -> n % 2 == 0).toArray();
}
}
Output:
[4, 8, 6]
What went wrong with your code:
result.length is 3 and therefore in result[], the maximum index you can access is 2 (i.e. result.length -1) whereas your second loop counter goes up to 5 (i.e. arr.length - 1) and you are using the same counter to access elements in result[] resulting in ArrayIndexOutOfBoundsException.
If you want to do it in your own way, you need to use a separate counter for result[] e.g.
int[] result = new int[length];
//add even ints to new array
for (int i = 0, j = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0) {
result[j++] = arr[i];
}
}
I am trying to check whether an element of array has a successor.in other words, make the Ascending sublist to 0 and the rest to 1. the first element of the inputArray should be ignored
if yes then the both element should be 0 if not then 1. For example: for the input
int[] arr = {1,8,1,9,10};
the output should be [1,1,1,0,0]
another example: for the input int[] arr = {1,2,3,9,100}; should the output be: [1,0,0,1,1]
This is my try, but it does not work as expected. Where am i making failur?
public class HelloWorld {
public static void main(String[] args) {
int[] arr = { 1, 8, 1, 9, 10 };
int[] listOutput;
for (int i = 1; i<arr.length - 1; i++) {
if (arr[i] - arr[i + 1] == -1) {
arr[i] = 0;
arr[i + 1] = 0;
} else {
arr[i] = 1;
}
}
System.out.println("Hello World");
for (int i = 0; i<arr.length; i++) {
System.out.println(arr[i]);
}
}
}
public static void main(String[] args) {
int[] arr = { 1, 8, 1, 9, 10 };
// assume arr.length >= 2
boolean asc = arr[1] - arr[0] == 1;
for (int i = 1; i < arr.length - 1; i++) {
if (arr[i + 1] - arr[i] == 1) {
arr[i] = 0;
asc = true;
} else {
if (asc) {
asc = false;
arr[i] = 0;
}
else {
arr[i] = 1;
}
}
}
arr[arr.length - 1] = asc ? 0 : 1;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
This will replace each ascending (by 1) sublist of size greater than 1 with 0s, and will replace each remaining element with 1 (besides the first element which remains unchanged).
You're looping the array from 1 instead of from 0.
I am developing a simple program to print seat numbers, where the row are numbered from 1-5 and columns from a-e. the code i am using is as follows
public class JavaApplication5 {
public static void main(String[] args) {
int j =1,k;
int i;
char c;
String[] arr = new String[25];
for( i = 0;i < arr.length;i++)
{
while(j <= 5)
{
for(k = 97;k < 102; k++)
{
c = ((char)k);
arr[i] = j + "" + c;
System.out.println(arr[i]);
}
j++;
}
}
}
}
this displays desired result. but when I print an element outside the for loop I get the result as null like below
public static void main(String[] args) {
int j =1,k;
int i;
char c;
String[] arr = new String[25];
for( i = 0;i < arr.length;i++)
{
while(j <= 5)
{
for(k = 97;k < 102; k++)
{
c = ((char)k);
arr[i] = j + "" + c;
}
j++;
}
}
System.out.println(arr[6]);
}
how to solve this?
this will leave all elements as null
String[] arr = new String[25];
this will iterate until j == 5 so only until arr[5]
while(j <= 5) {
j++;
}
Therefore arr[6] is still null
Change
arr[j] = j + "" + c;
instead of
arr[i] = j + "" + c;
Now it works.
public static void main(String[] args) {
int j = 1, k;
int i;
char c;
String[] arr = new String[25];
for (i = 0; i < arr.length; i++) {
while (j <= 5) {
for (k = 97; k < 102; k++) {
c = ((char) k);
arr[j] = j + "" + c;
}
j++;
}
}
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println(arr[5]);
System.out.println(arr[6]); // null because your check j <= 5 in while loop
}
You can access the array elements normally outside of the loop. In your example, arr[6] is just null. The fault is not in the way you access it. (Although i cant see the bug yet ;))
The problem in your code is that you simply write 5 time on index 1, then 5 time on index 2 and so on.
So you never wrote on index 6.
Your code should be changed to code below:
String[] arr = new String[25];
int i = 0;
int j = 1;
while (j <= 5) {
for (k = 97; k < 102; k++) {
c = ((char) k);
arr[i++] = j + "" + c;
}
j++;
}
System.out.println(arr[6]);
Because your loops run 5*5 times, then your i index will never pass arr array length.
But you better control it like this to prevent your code from being error prone:
if(i < arr.length) {
arr[i++] = j + "" + c;
} else {
break;
}
my code only misses 5 cases and i dont know why, somebody help me.
problem
Return a version of the given array where each zero value in the array
is replaced by the largest odd value to the right of the zero in the
array. If there is no odd value to the right of the zero, leave the
zero as a zero.
zeroMax({0, 5, 0, 3}) → {5, 5, 3, 3}
zeroMax({0, 4, 0, 3}) → {3, 4, 3, 3}
zeroMax({0, 1, 0}) → {1, 1, 0}
my code
public int[] zeroMax(int[] nums) {
int acum = 0;
int i = 0;
for( i = 0; i < nums.length;i++){
if(nums[i]==0){
for(int j = i; j < nums.length;j++){
if (nums[j]%2!=0){
acum = nums[j];
break;
}
}
nums[i]=acum;
}
}
return nums;
}
This can be done much more efficiently by rearranging the problem a bit.
Instead of traversing left-to-right, then scanning the integers on the right for the replacement, you can instead just go right-to-left. Then, you can store the previous replacement until you encounter a larger odd number.
public int[] zeroMax(final int[] nums) {
int replace = 0; // Stores previous largest odd - default to 0 to avoid replacement
for (int i = nums.length - 1; i >= 0; i--) { // start from end
final int next = nums[i];
if (next == 0) { // If we should replace
nums[i] = replace;
} else if (next % 2 == 1 && next > replace) {
// If we have an odd number that is larger than the replacement
replace = next;
}
}
return nums;
}
Given your examples, this output:
[5, 5, 3, 3]
[3, 4, 3, 3]
[1, 1, 0]
What you are missing is, that there could be more than one odd number on the right side of your zero and you need to pick the largest one.
Edit: And you also need to reset 'acum'. I updated my suggestion :)
Here's a suggestion:
public int[] zeroMax(int[] nums) {
int acum = 0;
int i = 0;
for (i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
for (int j = i; j < nums.length; j++) {
if (nums[j] % 2 != 0 && nums[j] > acum) {
acum = nums[j];
}
}
nums[i] = acum;
acum = 0;
}
}
return nums;
}
public int[] zeroMax(int[] nums) {
for (int i=0; i<nums.length; i++)
{
if (nums[i] == 0)
{
int maxindex = i;
for (int j=i+1; j<nums.length; j++)
{
if ((nums[j]%2 == 1) && (nums[j] > nums[maxindex]))
{
maxindex = j;
}
}
nums[i] = nums[maxindex];
}
}
return nums;
}
This alows you to find the index of the maximum odd number to the right, replacing the zero with the number at that index
The basic problem is that this algorithm doesn't search for the biggest odd value, but for the first odd value in the array, that is to the right of a given value. Apart from that, you might consider creating a table for the biggest odd value for all indices to simplify your code.
Here is one of the possible solutions to this :)
public int[] zeroMax(int[] nums) {
for(int i=0;i<nums.length;i++){
if(nums[i] == 0){
int val = largestOddValue(nums,i);//finding largest odd value
nums[i] = val; // assigning the odd value
}
}
return nums;
}
//finds largest odd value from the index provided to end
public int largestOddValue(int[] nums,int i){
int value = 0; // for storing value
for(int k=i;k<nums.length;k++){
if(nums[k]%2!=0 && value<nums[k]) // got the odd value
value = nums[k];
}
return value;
}
public int[] zeroMax(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == 0) {
int max = 0;
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] % 2 != 0 && nums[j] > max) {
max = nums[j];
}
}
nums[i] = max;
max = 0;
}
}
return nums;
}
public int[] zeroMax(int[] nums) {
int val = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 0) {
for(int j = i + 1; j < nums.length; j++) {
if(val <= nums[j]) {
if(nums[j] % 2 == 1) {
val = nums[j];
}
}
}
nums[i] = val;
val = 0;
}
}
return nums;
}
public int[] zeroMax(int[] nums) {
int[] result = nums.clone();
for (int i = nums.length - 1, max = 0; i >= 0; i--)
if (isOdd(nums[i])) max = Math.max(nums[i], max);
else if (nums[i] == 0) result[i] = max;
return result;
}
boolean isOdd(int num) { return (num & 1) == 1; }
We iterate backwards, always storing the biggest encountered odd number (or 0, if none was found) in max.
When we find a 0, we simply override it with max.
The input is untouched to avoid ruining somebody else's input.
Here is the code which works for every input. Try this on your IDE
public int[] m1(int a[]){
int j = 0;
for (int i = 0; i < a.length; i++) {
if(a[i]!=0){
continue;
}
else if(a[i]==0){
j=i;
while(j<a.length){
if(a[j] % 2 != 0){
if(a[i]<=a[j]){
a[i] = a[j];
j++;
}
else{
j++;
continue;
}
}
else{
j++;
continue;
}
}
}
}
return a;
}
I have taken array int[] a = {33,33,5,5,9,8,9,9}; In this array so many values are duplicates means 33 comes twice & 5 also comes twice & 9 comes three times.
But I want to count the first value which is duplicate means 33 is first value which comes twice so answer would be 2.
I try:
public class FindFirstDuplicate
{
public static void main(String[] args) {
int c=0;
int[] a = {33,33,5,5,9,8,9,9};
outerloop:
for(int i = 0; i < a.length; i++)
{
for(int j = i+1; j< a.length; j++)
{
if(a[i] == a[j])
{
System.out.println(a[i]); //Duplicate value
c++;
break outerloop;
}
}
}
System.out.print("Count: "+c);
}
}
Output:
33
1
public class HelloWorld{
public static void main(String[] args) {
int[] a = {33,33,5,5,9,8,9,9};
for(int i = 0; i < a.length; i++)
{
int c=1; // we already found one.
// and we initialize this counter inside the loop,
// so that it is reset for each new starting number.
for(int j = i+1; j< a.length; j++) // we're starting from next number (reason we start with c=1)
{
if(a[i] == a[j])
c++;
}
if(c > 0) {
System.out.println("First uplicate value: "+ a[i] + " Count: " + c);
break; // we have to break out of the outer loop,
// so the inner loop can finish counting duplicates
}
}
}
}
Try something like:
int[] numbers = {33, 33, 5, 5, 9, 8, 9, 9};
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i< numbers.length; i++) {
if (!set.add(number[i])) {
System.out.println("first duplicate is " + number[i] + " and index is " + i);
break;
}
}
If the values in the array are non-negative and reasonably small, you can use a BitSet to store whether or not you have seen a value previously:
BitSet bits = new BitSet();
for (int i = 0; i < numbers.length; ++i) {
if (bits.get(numbers[i])) {
System.out.println("first duplicate at " + i + ": " + numbers[i]);
break;
}
bits.set(numbers[i]);
}
You could try this out:
int[] a = {33,33,5,5,9,8,9,9};
Integer[] uniques = new Integer[a.length];
Integer[] counts = new Integer[a.length];
int len = 0;
for(int num : a){
boolean matched = false;
for(int i = 0; i < len; i++){
if(num == uniques[i].intValue()){
matched = true;
counts[i] = new Integer(counts[i]+1);
break;
}
}
if(!matched){
uniques[len] = new Integer(num);
counts[i] = new Integer(1);
len++;
}
}
for(int i = 0; i < len; i++){
if(counts[i].intValue() > 1){
System.out.println("first duplicate is " + uniques[i] + " and number of times it appears " + counts[i]);
break;
}
}
In your code you exit both loops after the first duplicate is found, so any other occurences of the element would be ignored.
Also you start with c = 0. When you get to the second occurence, c will be incremented and be 1, not 2.
To count all elements simply change the loop condition of the outer loop and remove the break:
int c = 1;
int i;
for(i = 0; (c == 1) && (i < a.length); i++)
{
for(int j = i+1; j < a.length; j++)
{
if(a[i] == a[j])
{
c++;
}
}
}
System.out.println(a[i]); //Duplicate value
System.out.print("Count: "+c); // maybe do something else, if c == 1 (no duplicates)???
However SMA's answer describes a more performant way (for arbitrary input arrays) of finding the first duplicate. Once you found the second occurence of the first duplicate, you'd only need to count the number of occurences in the rest of the array to get the final count.