Inserting items at a specific index in an array - IndexOutOfBounds exception - java

This feature is supposed to add an element at the selected index and push all other in the array elements down. So, for instance, say I have the following array:
[0] = zero
[1] = one
[2] = two
if I add another element at index 0 called NEWZERO, the array has to look like this:
[0] = NEWZERO
[1] = zero
[2] = one
[3] = two
but currently I'm getting IndexOutOfBounds exception and it doesn't work, although my array is much bigger than just 3 elements.
P.S. I don't want to use the built-in ArrayList library, which automatically does it for you.
public void insert(int i, String s) {
if (array[i] == null) {
array[i] = s; //Need to add feature that instantly puts the element at the first available spot on the list.
} else {
for (int j = i; j < array.length; j++) { //Can't use >= i
array[j + 1] = array[j]; //THIS IS WHERE I GET THE ERROR.
if (j == array.length - 1) {
break;
}
}
array[i] = s;
extendArray(); //If an element is inserted properly, the array becomes array.length + 1
I'm not getting the error because there's no space in my array. Even if I have an array with 20 elements, and I'm working with just 3, I still get the OutOfBounds error. Here's my extend array method for when a user runs out of array space.
public void extendArray() {
String[] items2 = new String[items.length + 1];
for (int j = 0; j < items.length; j++) {
items2[j] = items[j];
}
items = items2;
}

When you initializes an array, it exists from 0 to length-1 values.
in your code
for (int j = i; j < array.length; j++) { //Can't use >= i
array[j + 1] = array[j]; //THIS IS WHERE I GET THE ERROR.
you are trying to store values to array[length] that is out of the bounds of the array.
so change the for to
for (int j = i; j < array.length - 1; j++) { //Can't use >= i
array[j + 1] = array[j];

When j reaches array.length-1 in the loop, the array[j + 1] is out of bounds.
To fix this, change the stopping condition (and get rid of the break since it's completely unnecessary):
for (int j = i; j < array.length - 1; j++) {
array[j + 1] = array[j];
}
Finally, you might want to replace the entire loop with a single call to System.arraycopy().

You already have a condition for j in the loop, so why do you need to second one? Just use
for (int j = i; j < array.length - 1; j++) { //Can't use >= i
array[j + 1] = array[j];
}

try this fix
for (int j = i; j < array.length - 1; j++) { //Can't use >= i
array[j + 1] = array[j];
}
besides it makes sense to extend the size of the array before inserting the new element

When j wil reach at the end , j+1 will be out of bound and cause arrayIndexoutOfBoundException
Solution :
Change the for loop like below
for (int j = i; j < array.length - 1; j++) { //Can't use >= i
array[j + 1] = array[j];
}

Related

Pascal's triangle in Java [duplicate]

This question already has answers here:
Pascal's triangle positioning
(5 answers)
Closed 1 year ago.
Java beginner here! As part of practicing programming, I've run into Pascal's triangle. I tried to implement a solution where the triangle is printed like so:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
...
So roughly right-sided. My solution though runs into multiple errors, and although I would appreciate help with that, I would primarily like to know if I am thinking correctly with my solution. (For some functions I am using a custom library)
public static void main(String[] args) {
int input = readInt("Enter triangle size, n = ");
array = new int[input][input];
for (int i = 0; i < input; i++) { // rows
for (int j = 0; j < i + 1; j++) { // columns
if (i = 0) {
array[i][0] = 1;
} else if (i != 0 && i == j) {
array[i][j] = 1;
} else {
array[i][j] = array[i - 1][j] + array[i - 1][j - 1];
}
}
}
// print out only the lower triangle of the matrix
for (int i = 0; i < input; i++) {
for (int j = 0; j < input; j++) {
if (i <= j) {
System.out.println("%d ", array[i][j]);
}
}
}
}
You were on the right track. Here's how I implemented it:
Scanner sc = new Scanner(System.in);
System.out.print("Enter triangle size, n = ");
int n = sc.nextInt();
sc.close();
//This will be a jagged array
int[][] array = new int[n][0];
for (int i = 0; i < n; i++) {
//Add the next level (it's empty at the start)
array[i] = new int[i + 1];
for (int j = 0; j <= i; j++) {
//At the ends, it's just 1
if (j == 0 || j == i) {
array[i][j] = 1;
} else { //The middle
array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
}
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j <= i; j++) {
//printf is what you use to do formatting
System.out.printf("%d ", array[i][j]);
}
//Without this, everything's on the same line
System.out.println();
}
Your else part was correct, but you didn't check if j equaled 0 before that. Instead of setting the current element to 1 when i was 0 or when i equaled j, you should have done it when j was 0 or when i equaled j. Because of this mistake, in later rows where i was not 0, but j was, you tried to access array[i - 1][j - 1], which was basically array[i - 1][-1], causing an IndexOutOfBoundsException.
I also made a jagged array instead of an even matrix because it made more sense that way, but it shouldn't matter much.
Also, this wasn't an error, but you did else if (i!=0 && i==j) The i != 0 part is unnecessary because you checked previously if i == 0.
Link to repl.it

Java array/inverse novice

I'm a novice at java language, and I had a problem that I have to solve, I'm fairly sure that I've done it right yet the tester still crashes.
a brief summary of what if has to do is " Inside an array a, an inversion is a pair of positions i and j inside the array that satisfy simultaneously both i < j and a[i] > a[j]. In combinatorics, the inversion count inside an array is a rough measure how "out of order" that array is. If an array is sorted in ascending order, it has zero inversions, whereas an n-element array sorted in reverse order has n(n-1)/2 inversions, the largest number possible. This method should count the inversions inside the given array arr, and return that count "
here's what I've done/tried
import java.util.Arrays;
public class P2J1
{
public static int countInversions(int[] arr)
{
int inversions = 0;
for (int i = 0; i <= arr.length; i++){
for (int j = i+1; j < i; j++){
if (arr[i] > arr[j]){
inversions++;
}
}
}
return inversions;
}
}
/// here's the tester
#Test public void testCountInversions() {
Random rng = new Random(SEED);
CRC32 check = new CRC32();
for(int i = 0; i < 1000; i++) {
int[] a = new int[i];
for(int j = 0; j < i; j++) {
a[j] = rng.nextInt(100000);
}
check.update(P2J1.countInversions(a));
}
assertEquals(1579619806L, check.getValue());
}
In Java, the array indexing is from 0 to arr.length - 1, you need to change i <= arr.length in your code to i < arr.length. Otherwise you would get ArrayIndexOutofBoundsException
Also #khelwood's suggestion is true. Change (int j = i+1; j < i; j++) to (int j = i+1; j < arr.length; j++)

Magic Square gives ArrayIndexOutOfBoundException

I have been working on Magic Square formation, after reading through the algo, I found out there are certain set of rules to be followed while forming the MagicSquare.
The algo which I'm following is :
The magic constant will always be equal to n(n^2 + 1)/2, where n is the dimension given.
Numbers which magicSquare consists will always be equals 1 to n*n.
For the first element that is 1, will always be in the position (n/2, n-1).
Other elements will be placed like (i--,j++)
The condition to be put through for placing an elements are :
a) If i < 0, then i = n-1.
b) If j == n, then j = 0.
c) This is a special case, if i < 0 and j=n happens at the same time, then i = 0, j = n-2.
d) If the position is already occupied by some other element, then i++, j = j-2.
Then input the element inside the magicSquare based upon the conditions.
Based upon the above algo, I have written down a code, and due to some reason I'm getting
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Main.generateMagicSquare(Main.java:25)
at Main.main(Main.java:58)
This is weird. I have checked, and feels like it is safe to use the code to get the desired result, but I don't know where I'm going wrong.
Code
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
// if the element is already present
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
Any help would be appreciated. Thanks. Since I could have copied and pasted the code from internet, but I want to learn it in my way, and your help would help me achieve what I want. :)
EDITS
After reading through the exception, I made some amendments in my code, but still some of the result didn't come upto the mark.
Here is my updated code =======>
static void generateMagicSquare(int n){
int[][] magicSquare = new int[n][n];
//initialising for pos of the elem 1
int i = n/2, j = n-1;
magicSquare[i][j] = 1;
//the element consist by the magic square will always be equal to 1 to n*n
for(int num=2; num <= n*n; num++){
//it must go like this, for any other element
i--; j++;
if(i < 0){
i = n-1;
}
if(j == n){
j = 0;
}
if(i < 0 && j == n){
i = 0;
j = n-2;
}
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
magicSquare[i][j] = num;
}
}
for(int k=0; k<n; k++){
for(int l=0; l<n; l++){
System.out.print(magicSquare[k][l] + " ");
}
System.out.println();
}
}
I get this output :
2 0 6
9 5 1
7 3 0
Still not the right answer to follow.
This line throws the error:
if(magicSquare[i][j] != 0)
and the problem is that the array magicSquare is initialized as:
int[][] magicSquare = new int[n][n];
meaning that it has n columns with indexes from 0 to n - 1 (indexes are zero based).
The variable j is initialized as
j = n-1;
and later this line:
j++;
makes j equal to n
so when you access magicSquare[i][j] you are trying to access magicSquare[i][n] which does not exist.
The index of an array is an integer value that has value in interval [0, n-1], where n is the size of the array. If a request for a negative or an index greater than or equal to size of array is made, then the JAVA throws a ArrayIndexOutOfBounds Exception. You have to check the value of i and j before using it in array. You can use the below code :
for(int num=2; num <= n*n; num++){
i--; j++;
//Here We have to check the value of i and j i.e. it should less than or equal to the length of array.
if((i <= magicSquare[0].length-1 && j <= magicSquare[0].length-1))
{
if(magicSquare[i][j] != 0){
i++;
j -= 2;
}else{
if(i < 0)
i = n-1;
if(j == n)
j = 0;
if(i < 0 && j == n){
i = 0;
j = n-2;
}
}
magicSquare[i][j] = num;
}
}
For understanding ArrayIndexOutOfBoundsException, Please visit :
https://www.geeksforgeeks.org/understanding-array-indexoutofbounds-exception-in-java/

Number of Comparisons in Bubble Sort

I am trying to make a method for comparisons in my bubble sort class. However, I keep getting the same value. Is there any way to fix this? Thanks.
public void comparisons(int[] array)
{
int count = 0;
for (int i = 0; i < array.length - 1; i++)
{
for (int j = 0; j < array.length - i - 1; j++)
{
count++;
if ((array[i] > array[i + 1])) //Swaps the elements
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
}
System.out.print("\n\nComparisons:" + count);
}
The inner loop index j is not used, and it has incorrect bounds.
public void comparisons(int[] array)
{
int count = 0;
for (int i = 0; i < array.length - 1; i++)
{
for (int j = i; j < array.length - 1; j++)
{
count++;
if ((array[j] > array[j + 1])) //Swaps the elements
{
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
System.out.print("\n\nComparisons:" + count);
}
The outer loop index i is the same value for all the values of j in the inner loop. Looks like the compare logic should be using the inner loop index j.
If count is supposed to record the number of swaps done during the sort, perhaps it needs to be in the block of code performing the swap. At the moment, count++ will always execute the same number of times.
Try this:
public void comparisons(int[] array)
{
int count = 0;
for (int i = 0; i < array.length - 1; i++)
{
for (int j = 0; j < array.length - i - 1; j++)
{
if ((array[i] > array[i + 1])) //Swaps the elements
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
count++;
}
}
}
System.out.print("\n\nComparisons:" + count);
}
You better try to increment value of count inside the if-condition. You can place count++ anywhere inside if-condition, based upon requirements.

Using a For Loop to Manually Sort an Array - Java

I'm having trouble manually sorting the array with a for loop. It works except for the first and last number. Here's my code:
Scanner numInput = new Scanner(System.in);
int tempVar, num;
String numbersString;
int[] numbers = {4, 11, 13, 12, 17, 35, 15, 7, 19, 3, 45};
for (int i = 0; i < numbers.length - 1; i++)
{
for(int j = 0; j < numbers.length - 1; j++)
{
if(numbers[i] < numbers[j + 1])
{
tempVar = numbers [j + 1];
numbers [j + 1]= numbers [i];
numbers [i] = tempVar;
}
}
}
numbersString = Arrays.toString(numbers);
System.out.println(numbersString);
You have to initialize the value for j as i+1, this sorting algorithm is called bubble sort, that works by repeatedly swapping the adjacent elements if they are in wrong order. The below method is always runs O(n^2) time even if the array is sorted.
public static void main (String[] args)
{
int[] array = {4,2,1,3,5,9,6,8,7};
for(int i = 0 ; i < array.length;i++)
{
for(int j = i+1 ; j< array.length;j++)
{
if(array[i] > array[j])
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
public int[] sort(int[] arr) {
int marker, i, temp;
marker =0;
i = 1;
while (marker < arr.length - 1) {
if (i == arr.length) {
marker++;
i = marker;
}
if (arr[marker] > arr[i]) {
temp = arr[marker];
arr[marker] = arr[i];
arr[i] = temp;
}
i++;
}
return arr;
}
Try this one:
int temp = 0;
for (int i = 0; i < numbers.length - 1; i++) {
for (int j = i + 1; j < numbers.length; j++) {
if (numbers[i] > numbers[j]) {
temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
}
}
You have little wrong second for iteration and reverse condition.
you have some errors in your code. I make some modifications, please look:
int tempVar, num;
String numbersString;
int[] numbers = {4, 11, 13, 12, 17, 35, 15, 7, 19, 3, 45};
for (int i = 0; i < numbers.length; i++) {
for (int j = i; j < numbers.length; j++) {
if (numbers[i] < numbers[j]) {
tempVar = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tempVar;
}
}
}
numbersString = Arrays.toString(numbers);
System.out.println(numbersString);
First, I recommend you to iterate in the second loop, from i (beacause the items previous i are now sorted).
Second, you have to switch the items on i and j positions.
Finally, beacause you use < strict comparator un your loops break, you have to go user numbers.length and not numbers.length - 1 .
For more information, please see the buble sort algorithm
I will provide a modified version of your code with the intention of explaining why your code does not work.
First, we need to decide specifically what we want to do. Lets say we want to sort the numbers in descending order.
What does this mean? Every time when we are comparing two values at lowIndex and highIndex, we want to make sure that the value at lowIndex is higher than the value at highIndex.
The problem with your code is that it does not keep track of which index, i or j+1, that is lower.
When i==1 and j+1==2, your code will swap the values so that the greatest value out of numbers[1] and numbers[2] will be put at index 1.
When i==2 and j+1==1, your code will swap the values so that the smallest value out of numbers[1] and numbers[2] will be put at index 1.
This is incosistent. The algorithm is competing with itself, trying to move values in different directions. If we modify your code to check that we are consistent in whether we want to swap large values towards the beginning of the array or towards the end, your algorithm will start to work:
for (int i = 0; i < numbers.length - 1; i++)
{
for(int j = 0; j < numbers.length - 1; j++)
{
if(numbers[i] < numbers[j + 1] && i < (j + 1)) //NOTE: additional condition for indices
{
tempVar = numbers [j + 1];
numbers [j + 1]= numbers [i];
numbers [i] = tempVar;
}
}
}
Note, however, that the example above is just for explaining what goes wrong in execution of your code. Rather than using this code, it would probably be more appropriate to use one of the other answers to this question, or study and compare sorting algorithms on wikipedia
Try this
class desc
{
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
System.out.print(" "+arr[i]);
}
}
void sort(int arr[],int n)
{
for (int i = 1; i < n; i++)
{
if(arr[i] < arr[i - 1] )
{
arr[i] = arr[i] + arr[i - 1];
arr[i - 1] = arr[i] - arr[i - 1];
arr[i] = arr[i] - arr[i - 1];
i=0;
}
}
}
public static void main(String []args)throws Exception
{
int[] arr = {-5, 0, -7, -2, -5, 1, -9, -1};
int n = arr.length;
desc d=new desc();
d.sort(arr,n);
d.printArray(arr, n);
}
}
I believe what you are willing to do is selection sort? https://en.wikipedia.org/wiki/Selection_sort An other option I see is bubble sort but I'll try to explain selection sort.
So the first iteration of the outer for loop, the one with i, you check the whole array for the smallest number with the inner for loop, the one with j, and you put the smallest number upfront in the array. During the second iteration of the outer for loop you only go over the numbers you haven't checked yet, which is the second number through the last number. During the third iteration you go over the third number through the last number and so on. Here's how I adjusted your code, I adjusted the inner for loop so with each iteration you check a smaller sub-list and adjusted your if clause so that the smallest number is found:
int tempVar;
String numbersString;
int[] numbers = {4, 11, 13, 12, 17, 35, 15, 7, 19, 3, 45};
for (int i = 0; i < numbers.length - 1; i++)
{
// each iteration i you would need to go over a smaller array, so you set j = i each time
for(int j = i; j < numbers.length - 1; j++){
// checking if numbers[i] is greater than numbers[j + 1] instead of smaller than
if(numbers[i] > numbers[j + 1]){
tempVar = numbers [j + 1];
numbers [j + 1]= numbers [i];
numbers [i] = tempVar;
}
}
}
numbersString = Arrays.toString(numbers);
System.out.println(numbersString);
for(int i = 0; i < nums.length - 1; ++i){
for(int j = i + 1; j < nums.length; ++j){
if(nums[i]>nums[j]){
int tempVar = nums[i];
nums[i] = nums[j];
nums[j] = tempVar;
}
}
}
return nums;
}

Categories

Resources