ArrayOutOfBoundsException in java - java

I have following code in Java.
public class TestArray
{
public static void main(String s[])
{
int arr[]={23,12,1,4,1,4,23,6};
int temp=arr[0];
for(int i=0;i<arr.length;i++)
{
for(int j=0;j<arr.length;j++)
{
if(arr[i]>arr[j+1])
{
temp=arr[j+1];
arr[j+1]=arr[i];
arr[i]=temp;
}
if(arr[i]==arr[j+1])
{
arr[j+1]=arr[j+2];
}
}
}
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
But this code is throwing
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 8
at com.test.java.TestArray.main(TestArray.java:16)
Could anyone help me with this ?

An attempt to index arr[j + 1] or arr[j + 2] will fail when j is arr.length - 1.
Should you run your indexes to one less than you currently do? Also, that final flourish where you index j + 2 looks unnecessary.
As a style point, keep the scope of temp as tight as possible. You only need it when you swap two array elements.

Looks like you are trying to sort the array in descending order. You can try this:
public class TestArray
{
public static void main(String s[])
{
int arr[]={23,12,1,4,1,4,23,6};
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){
if(arr[j-1] < arr[j]){
//swap elements
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);
}
}
}
You can understand the code.
If you are wondering how you got exception, refer answer by Bathsheba

Modify your code into
for(int i=0;i<arr.length-1;i++) {
for(int j=i;j<arr.length-1;j++) {
if(arr[i]>arr[j+1]) {
temp=arr[j+1];
arr[j+1]=arr[i];
arr[i]=temp;
}
if(arr[i]==arr[j+1]) {
arr[j+1]=arr[j+2];
}
}
}
In your loop, value of j will be from 0 to 7. And you are trying to access the j+1'th position of array. So when j has value 7 you are accessing a[8] and it is not within the bounds of the array size. An array of size 8 will have index values from 0 to 7.

Related

Java : Selection Sort Logic

I am printing Sorted Array elements using Selection Sort. But I am getting my input array elements as output in same sequence without sorting.
public class SelectionSort {
public static void main(String[] args) {
int[] arr= {1,9,3,0,7};
int n=arr.length;
for(int i=0; i<n-1; i++)
{
int minimumIndex = i;
for(int j=i; j<n; j++)
{
if(arr[j]<arr[minimumIndex])
{
minimumIndex=j;
}
}
int temp=arr[i];
arr[i]=arr[minimumIndex];
arr[i]=temp;
}
for(int e: arr)
{
System.out.print(e+" ");
}
}
}
Expected o/p : 0 1 3 7 9
Actual o/p: 1 9 3 0 7
In Your method code, the actual problem is swapping elements,
the Sequence needs to be like this as below,
int temp=arr[minimumIndex];
arr[minimumIndex]=arr[i];
arr[i] =temp;
instead of
int temp=arr[i];
arr[i]=arr[minimumIndex];
arr[i]=temp;
There are two issues I see. One is the way you are swapping the items. You need to replace the item where you found the minimum index. Also, your J index should start one after your I index. You can assume that the one before it is the smallest as you are looping through. I have changed a few pieces of the code and tested it and it works fine for me.
for (int i = 0; i < arr.length - 1; i++)
{
int minimumIndex = i;
for (int j = i + 1; j < arr.length; j++)
{
if (arr[j] < arr[minimumIndex])
{
minimumIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minimumIndex];
arr[minimumIndex] = temp;
}

Unable to find source of ArrayIndexOutOfBoundsException

I need some help to identify why this code is throwing an ArrayIndexOutOfBoundsException:
public class palindrome
{
public static void main(String[] args)
{
String name = "Michael Knight";
char ch[] = name.toCharArray();
int size = name.length();
for(int i = 0; i<size; i++) {
//System.out.println(size);
System.out.println(ch[i]);
for(int j=size; j>=0; j--) {
System.out.println(ch[j]);
}
}
}
}
ch[j] is out of bounds when j==size, since the indices go from 0 to size-1.
It should be :
for(int j=size-1; j>=0; j--){
System.out.println(ch[j]);
}
In the for loop, the j starts at index j=size which is already out of array bounds since the array starts from 0 to size - 1, thus ch[j] throws an ArrayIndexOutOfBoundsException.
The correct way to loop in reverse should be:
for(int j= (size - 1); j>=0; j--){
System.out.println(ch[j]);
}
try like this;
public class palindrome{
public static void main(String []arg$){
String name = "Michael Knight";
char ch[] = name.toCharArray();
int size = name.length();
for(int i = 0; i<size; i++){
//System.out.println(size);
System.out.println(ch[i]);
for(int j=size-1; j>=0; j--){
System.out.println(ch[j]);
}
}
}
}
for(int j=size; j>=0; j--) {
System.out.println(ch[j]);
j=size is out of bounds .
The last index of array is size-1.
j should be initialized with the last index of array in this case.

No duplicates in an array [duplicate]

This question already has answers here:
How to get unique values from array
(13 answers)
Closed 8 years ago.
void RemoveDups(){
int f=0;
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
{
arr[k]=arr[k+1];
}
nelems--;
}
if(i==(nelems+1)){
f++;
i=f+1; //increment again
}
}
}
This is the logic i have written to remove duplicate elements from an array ,but this is not working at all ?what changes i should make to make it work? or you people have better logic for doing the same considering time complexity.and i don't want to use built-in methods to achieve this.
int end = input.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (input[i] == input[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
input[shiftLeft] = input[k];
}
end--;
j--;
}
}
}
I think you can use Set Collection
copy all the values to an HashSet and then using Iterator access the Values
Set<Integer> hashset= new HashSet<Integer>();
You have two options, C# has the Distinct() Linq expression that will do this for you (Missed the Java tag), however if you need to remove items, have you thought about sorting the list first, then comparing the current item to the previous item and if they're the same, remove them. It would mean your diplicate detection is only ever running through the array once.
If you're worried about sort you could easily implement an efficient bubble sort or somthing to that effect
You never decrease i after You compared for examlpe arr[0] to arr[5], You never will test arr[1] == arr[2]
You need to start a new loop (i) after You've incremented f.
try
for(int f=0;f<nelems-1;f++)
{
for(int i=f+1;i<nelems;i++)
{
...
}
}
with this nested for loop you can compare every two element of the array.
a good start is to eliminate duplicate elements without shrinking the array which is done lastly:
public class run2 extends Thread {
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] == -1)
j++;
if (arr[i] == arr[j])
arr[j] = -1;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == -1) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != -1) {
arr[i] = arr[j];
arr[j] = -1;
break;
}
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
Adapt this code :
public static int[] removeDuplicates(int[] numbersWithDuplicates) {
// Sorting array to bring duplicates together
Arrays.sort(numbersWithDuplicates);
int[] result = new int[numbersWithDuplicates.length];
int previous = numbersWithDuplicates[0];
result[0] = previous;
for (int i = 1; i < numbersWithDuplicates.length; i++) {
int ch = numbersWithDuplicates[i];
if (previous != ch) {
result[i] = ch;
}
previous = ch;
}
return result;
}
As far as I understood from your code,you are comparing each value starting from index 0 to the rest of the element and when you see the element which is located at index f your are trying to shift the entire array and decrementing the size of array(nelems).Look at line no. 11
if(i==(nelems+1)){
f++;
i=f+1;
The problem is when i is set to f+1,i will again be incremented in the for loop for the next iteration.So basically i starts comparing from f+2.And also you are comparing i with (nelems+1) considering the case when nelems decremented but you are not considering the case when i reaches the end without decreasing nelems in that case i will never be equale to (nelems+1).Now considering your logic you could do 2 things.
1.Here is your working code.
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i+1;k<nelems;k++)
{
arr[k-1]=arr[k];
}
if(i==(nelems-1)){
f++;
i=f;
}
nelems--;
}
if(i==(nelems-1)){//end of the loop
f++;
i=f; //increment again
}
}
2.You could use an outer for loop alternatively that will increment the f value once the inner for is completed.
void RemoveDups(){
for(int f=0;f<nelems;++f){
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
arr[k]=arr[k+1];
nelems--;
}
}
}
}
Now your problem is solved but the time complexity of your code will be(O(N^3)).
Now instead of shifting the entire array at line 4,you could just swap the arr[f] with last element.
if(arr[f]==arr[i]){
swap(arr[f],arr[nelems-1]);
nelems--;
}
it will reduce the time complexity from O(N^3) to O(N^2).
Now I'll suggest you my method
1.just sort the array.It will be done in O(NlogN).
2.now using one for loop you can get what do you wanted.
void RemoveDups(){
int k=0,i;
for(i=1;i<nelems;++i){
while(arr[i]==arr[i-1])
++i;
arr[k++]=arr[i-1];
}
arr[k++]=arr[i-1];
}
Now basically you got an array of size k,which contains non repeated element in sorted order and the time complexity of my solution is O(NlogN).

Array Index Out of Bounds Exception in Java in case of Insertion Sort

class Insertionsort
{
int A[] = {5,2,4,6,1,3};
void insertionSort()
{
for(int j=2;j<A.length;j++)
{
int key = A[j];
int i = j-1;
while(i>0 && A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
}
for(int j = 0;j<=A.length;j++)
{
System.out.println(A[j]);
}
}
public static void main(String args[])
{
Insertionsort is = new Insertionsort();
is.insertionSort();
}
}
Problem is:
The Output of this is 5 1 2 3 4 6 instead of 1 2 3 4 5 6.
What to do?
This is causing the error:
for(int j = 0;j<=A.length;j++)
System.out.println(A[j]);
Max index of an array is length - 1 so change it to:
for(int j = 0;j<A.length;j++)
System.out.println(A[j]);
Better yet, why not use the enhanced for? That way you don't make this kind of mistake:
for(int a : A)
System.out.println(a);
Back to your algorithm:
Starting from j=2 you leave out your first element so change it to j=1.
Also your inner loop should go until i>=0 else you also leave out the 0th element (array index is 0-based):
for (int j = 1; j < A.length; j++) {
int key = A[j];
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i = i - 1;
}
A[i + 1] = key;
}
This will print out 1 2 3 4 5 6 (in new lines since println() is used).
If you want to sort an Array, you just need to use Sort() from Arrays class.
Arrays.sort(yourArray);
for(int j = 0;j<=A.length;j++)
change to j<A.length to make your OutOfBounds Exception go away.
also, your other loops have wrong start/end conditions
for(int j=2;j<A.length;j++) should start at j=1 and while(i>0 && A[i]>key) should have i>=0 or the first element in the array will be skipped in your sort (the 5).
In your sorting loop you initialize j = 2 and then get an number from the array with int key = A[j]; so the first number in the array you try to sort is index 2. Since the first element in an array has the index 0, you are leaving out 5 and 2 when sorting. Change the loop to
for(int j = 0; j < A.length(); j++){
int key = A[j];
int i = j-1;
....
class Insertionsort
{
int A[] = {5,2,4,6,1,3};
void insertionSort()
{
for(int j=1;j<A.length;j++)
{
int key = A[j];
int i = j-1;
while(i>=0 && A[i]>key)
{
A[i+1]=A[i];
i=i-1;
}
A[i+1]=key;
}
for(int j = 0;j<A.length;j++)
{
System.out.print(A[j] + " ");
}
}
public static void main(String args[])
{
Insertionsort is = new Insertionsort();
is.insertionSort();
}
}

Java: Combination of recursive loops which has different FOR loop inside; Output: FOR loops indexes

currently recursion is fresh & difficult topic for me, however I need to use it in one of my algorithms.
Here is the challenge:
I need a method where I specify number of recursions (number of nested FOR loops) and number of iterations for each FOR loop. The result should show me, something simmilar to counter, however each column of counter is limited to specific number.
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
public void recursion(ArrayList<Integer> specs){
//number of nested loops will be equal to: specs.size();
//each item in specs, specifies the For loop max count e.g:
//First outside loop will be: for(int i=0; i< specs.get(0); i++)
//Second loop inside will be: for(int i=0; i< specs.get(1); i++)
//...
}
The the results will be similar to outputs of this manual, nested loop:
int[] i;
i = new int[7];
for( i[6]=0; i[6]<5; i[6]++){
for( i[5]=0; i[5]<7; i[5]++){
for(i[4] =0; i[4]<9; i[4]++){
for(i[3] =0; i[3]<2; i[3]++){
for(i[2] =0; i[2]<8; i[2]++){
for(i[1] =0; i[1]<9; i[1]++){
//...
System.out.println(i[1]+" "+i[2]+" "+i[3]+" "+i[4]+" "+i[5]+" "+i[6]);
}
}
}
}
}
}
I already, killed 3 days on this, and still no results, was searching it in internet, however the examples are too different. Therefore, posting the programming question in internet first time in my life. Thank you in advance, you are free to change the code efficiency, I just need the same results.
// ...
recursion (specs, specs.size () - 1);
// ...
public void recursion(ArrayList<Integer> specs, int startWith){
for (int i = 0; i < specs.get(startWith); i++) {
// ...
if (startWith - 1 >= 0)
recursion (specs, startWith - 1);
}
}
Your function also need to now the index of the specs array to use for iteration, and also the previous numbers that should be printed:
public void recursion(ArrayList<Integer> specs, int index, String output) {
if( index >= specs.size() ) {
System.out.println(output);
return;
}
for (int i = 0; i < specs.get(index); i++ )
recursion( specs, index+1, Integer.toString(i) + " " + output );
}
The you should call it like this:
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5);
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
recursion( specs, 0, "" );
Does this snippet give the output you want? (It is compileable and executeable)
import java.util.ArrayList;
import java.util.List;
public class SO {
static ArrayList<Integer> specs = new ArrayList<Integer>();
static int[] i;
public static void main(String[] args) throws Exception {
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
i = new int[specs.size()];
printMe(0, specs, i);
}
static void printMe(int depth, List<Integer> _specs, int[] i) {
if (_specs.isEmpty()) {
System.out.println(printI(i));
return;
} else {
for (int j = 0; j < _specs.get(0); j++) {
i[depth] = j + 1; // + 1 since you seems to want to go from 1 and not 0
printMe(depth + 1, _specs.subList(1, _specs.size()), i);
}
}
}
static String printI(int[] i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i.length; j++) {
sb.append(i[j]);
if (j < i.length - 1) {
sb.append(" ");
}
}
return sb.toString();
}
}
You can try this :
public static void loops(ArrayList<Integer> specs, int idx, StringBuilder res){
if(idx==specs.size()-1){
for (int i = 0; i < specs.get(idx); i++) {
System.out.println(i+" "+res);
}
}
else{
for(int i=0;i<specs.get(idx);i++){
res.insert(0,i+" ");
loops(specs,idx+1,res);
res.delete(0, 2);
}
}
}
And call with :
ArrayList<Integer> specs= new ArrayList<Integer>();
specs.add(5); //for(int i=0 to 5; i++)
specs.add(7);
specs.add(9);
specs.add(2);
specs.add(8);
specs.add(9);
loops(specs,0, new StringBuilder());

Categories

Resources