Understanding the logic of an add to an array method - java

This method is used to insert the element toAdd as the new first element of the array arr, shifting all of the current elements over to make space. The original last element of the array will just be lost. The method has no return value and if the array has no elements it should have no effect.
public static void insert(int[] arr, int toAdd){
if(arr.length > 0) {
for(int i = arr.length - 1; i > 0; --i) {
arr[i] = arr[i - 1];
}
arr[0] = toAdd;
}
}
I understand the part about if(arr.length > 0) this guarantees that we are working with an array with at least 1 element. The rest of the logic confuses me. Why set i = arr.length, why a - 1 afterward? why i > 0? and --i?
Thank you

You are browsing your array from its last element to the first, while shifting each element over by one. For example, when i = 3 we moving element 2 to position 3.
But this method doesn't work. A correct version would be:
public static void insert(int[] arr, int toAdd){
if(arr.length > 0) {
for(int i = arr.length - 1; i > 0; i--) {
arr[i] = arr[i - 1];
}
arr[0] = toAdd;
}
}
--i reduce the value of i before its use so it should be i-- or i should begin at arr.length or else you won't move the last element.

arr.length will return the number of elements in the array. If you had an array with elements at index 0, 1, and 2, it would return "3". The problem is that the array index is inclusive at 0, so you need to subtract 1 from the length to get the valid index of the last element in the array. (ie 3 - 1 = 2 and 2 is the true index of the last element)
The loop uses i > 0 because the index i is being decremented (ie i = i -1) by the '--i'. So the loop is starting at the highest element in the array (length -1), and counting down to the lowest (index 0).
Lastly, the line assigning toAdd to 0 should be outside of the for loop.

Why set i = arr.length and --i?
It is i = arr.length-1 and this the last index of the array. You have to start shifting elements looping backwards (--i, i-- would be ok, too), otherwise you'll be overriding elements before you can shift them.
why i > 0?
arr[0] = toAdd; should be outside of the loop and would fail for arr.length == 0.
You can simplify to:
public static void insert(int[] arr, int toAdd){
if(arr.length > 0) {
for(int i = arr.length - 1; i > 0; --i)
arr[i] = arr[i - 1];
arr[0] = toAdd;
}
}

Related

Reversing elements in array

I've been looking at a for-loop that reverses the elements in an array, but I do not quite understand what's going on inside it. This is the code:
int middleIndex = (array.length) / 2;
for (int i = 0; i < middleIndex; i++) {
int temporaryVariable = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = temporaryVariable;
}
What exactly does the two lines below int temporaryVariable = array[i] do? How exactly does it reverse the elements?
It effectively reverses the elements of the array by swapping first with last element, second with second_last etc. In this way the number of operations are ayrray_length / 2.
The 2 lines after int temporaryVariable = array[i]; simply swap the i'th element with the i'th from last element, and we run this loop half time the number of elements in array.
First of all remember that array indexes start from 0.
So the index of the last element is the array.length - 1.
Those 3 lines are swapping the first item with the last item, then the 2nd item with the 2nd-from-last item, etc. The temporaryVariable is used as a temporary place to store one of the values during swapping, so that it doesn't get lost when it is overwritten by the other value.
Take a copy of the value at i:
int temporaryVariable = array[i];
Put item i from the end of the array (array.length - 1 - i) instead of it.
array[i] = array[array.length - 1 - i];
Put the temporarily stored item which was item i at i from the end (array.length - 1 - i).
array[array.length - 1 - i] = temporaryVariable;
The loop stops when i reaches the middle of the array. (If the array has an odd number of elements the middle one stays where it is.)
This algorithm is taking N/2 iterations of swapping values stored in an array. It starts from the beggining of the array (Index 0) and goes until its half(index N/2). It swaps the first element(indexed 0) with the last one (indexed N - 1 - 0), then swaps the second element(indexed 0 + 1) with the one before the last one(indexed N - 1 - (0 + 1)), and so on.
another part was to return the second biggest number, but for some reason it returns the third biggest number, which is really weird.
This is the code:
public static int returnSecondBiggest(int[] array) {
int largestElement = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > largestElement) {
largestElement = array[i];
}
}
int secondBiggest = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] > secondBiggest && array[i] != largestElement) {
secondBiggest = array[i];
}
}
return secondBiggest;
}
How does it return the third when the code should return the second? I'm so lost.

Java ArrayList break remove

I was trying to write a code that would remove all zeros before the first non-zero element in an integer ArrayList, scanned from index 0. However, the code keeps on removing a fixed no. of zeros after the first non-zero element. can anybody figure out why?(Sorry if format of question posted is not ideal. this is my first time.)
For the following code, the intended output was [2 0 0 0 0 0], but the output received was [2 0 0]
class Zeroeliminator {
public static void main(String args[]) {
ArrayList < Integer > arr = new ArrayList < Integer > ();
arr.add(0); // A
arr.add(2);
for (int i = 2; i < 7; i++)
arr.add(0);
System.out.println(arr.size());
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) != 0) {
break;
}
System.out.println(arr.get(i));
arr.remove(i);
}
System.out.println(arr.size());
ListIterator < Integer > itr = arr.listIterator(0);
while (itr.hasNext()) {
System.out.print(itr.next() + " ");
}
System.out.println();
}
}
The problem with your code is that when you remove an element, all of the elements after it are shifted down by one. So, the state of one iteration looks like this:
arr=[0 2 0 0], i = 0
// Remove element i
arr=[2 0 0], i = 0
// Increment i
arr=[2 0 0], i = 1
On the next iteration, you'll check for i = 1, and ignore the fact there was a 2 there, because you never read its value.
You can fix this by decrementing i each time you remove an element. But you don't then need i at all, because you're removing the list prefix. Instead, you could just use:
while (!arr.isEmpty() && list.get(0) == 0) {
arr.remove(0);
}
A better (more efficient) approach to this is to scan through the list first to find the first non-zero element, and then delete the preceding elements in one go:
int i = 0;
while (i < arr.size() && arr.get(i) == 0) {
i++;
}
arr.subList(0, i).clear();
Removing 1 element from the front of an ArrayList is O(size), because all of the other elements have to be shifted down by one; so removing multiple elements is O(#removed * size).
The approach using sublist does all of the shifts in one go, so it is O(size).
You have to decrement i when you remove an element, since the indices of the ArrayList elements following the removed element are decremented.
for(int i = 0; i < arr.size(); i++)
{
if(arr.get(i) != 0){
break;
}
System.out.println(arr.get(i));
arr.remove(i);
i--;
}

When to add -1 to array recursion?

I can't understand one thing, when do I need to add -1 to arr.length and when I don't need to add -1?
For example, this code will only work if I add -1:
public boolean array220(int[] nums, int index) {
if(index >= nums.length - 1)
return false;
if(nums[index] * 10 == nums[index + 1])
return true;
return array220(nums, index + 1);
}
And this code will only work if I won't add -1:
public int array11(int[] nums, int index) {
if(index >= nums.length)
return 0;
if(nums[index] == 11)
return 1 + array11(nums, index + 1);
return array11(nums, index + 1);
}
In the first example you access elements of the array using both nums[index] and nums[index+1].
Since the array lookup value must be < nums.length, the constraint is:
index+1 < nums.length
aka:
index < nums.length - 1
which means you exclusion logic is the reverse test:
if (index >= nums.length - 1)
In the second example, you only access nums[index], so:
index < nums.length
giving exclusion logic as:
if (index >= nums.length)
Since arrays are zero-based, arr.length is the size of the array, in the number of elements. This means that the last index is at arr.length-1, since 0 is the first element.
There's no clear cut rules, as for example if you use >= instead of > (or more usually <= vs. <, like in a simple for loop) you need to adjust your values.
If your array is empty, it contains 0 elements and the length is 0.
If your array has 1 element in 0 index, then the length is 1.
If your array has 2 elements in 0 and 1 indexes, then the length is 2.
and so on..
we can notice , that the first index of every array is 0 so the last index is always array.length-1.
therefore we can use two methods
first method
:if you want to use <
so the code will be something like (note that in the end , i will be equal to array.length-1)
for(int i=0;i<arr.length;i++)
second method:if you want to use <=
so the code will be something like (note that in the end , i will also be equal to array.length-1)
for(int i=0;i<=arr.length-1;i++)

Removing an element from ArrayList

I have an ArrayList which contain 10 elements and a variable int = 12. Now I want to count how many elements are in array and if are less than 12 to start to count again from 0 and stop to index 2 and remove it, until I will have one element in my array. I tried the following:
int j = 12;
int l = 0;
// Here I check if j is less than array.size
while (j < array.size()) {
for (int i = 0; i < array.size(); i++) {
if (j == i + 1) {
array.remove(i);
}
}
}
// Here is for j greater than array.size
while (array.size() != 1) {
for (int i = 0; i < array.size(); i++) {
l = j - array.size();
if (l < array.size()) {
array.remove(l);
}
}
}
System.out.println(array);
UPDATE:
MyArray = {1,2,3,4,5,6,7,8,9,10};
int=12;
MyArray contain just 10 elements, but I want to delete the index with number 12, as long as index 12 does not exist I should start to count again from zero, and the number 12 is at index 2, That's why I should delete the index with number 2. The second iteration MyArray will contain just 9 elements, and again 12-9=3, I should delete the index with number 3, until I will have just one element in MyArray
Instead of looping twice through the array to remove the last n elements until the length of the list equals j, you could simply use:
while (j < array.size()) {
array.remove(j - 1);
}
If you always want to remove index 2, you could do:
while (array.size() >= 3) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(2);
}
However, you will have two elements left in your ArrayList instead of 1 (at index 0 and 1). You cannot delete ìndex 2 at that point, because it is not a valid index any longer.
Thus, you could either remove index 0/1 afterwards or what I think you want to achieve:
while (array.size() >= 2) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(1);
}
Then only one element will remain in your list at index 0.
Edit: for the update of your question it is
int originalSize = array.size();
while (array.size() >= originalSize - j) { // otherwise you will get a ArrayIndexOutOfBoundsException
array.remove(originalSize - j);
}
However, you will always be left with size - j items in your list. You cannot remove index 3, for example, until you have only one element in your list.
An answer to the updated question:
When you have a list of length 10 and you want to delete the "12th element" you can use the modulo operator:
ArrayList<...> someList = ...;
int toDelete = 12;
int deleteInRange = toDelete % someList.size();
someList.remove(deleteInRange);
The modulo operator will deliver the rest of the integerdivision 12 / 10 (toDelete % someList.size())
You can use this code snippet in a loop in order to remove multiple elements.
If you always want to remove index 2, you could do:
l = j - array.size();
Change this line as below:
int sum = 0;
sum = l - array.size();
if (sum > 0) {
array.remove(sum);
} else {
sum = array.size() - l;
array.remove(sum);
}

Out of Bounds of an Array [Bubble Selection with ArrayList]

I'm coding a Bubble Selection method, which should work with these credentials:
/* Write code for a Bubble Sort algorithm that starts at the right side of
* of ArrayList of Comparable objects and "bubbles" the largest item to the
* left of the list. The result should be an ArrayList arranged in descending
* order.
*/
#SuppressWarnings("unchecked")
void bubbleSort(ArrayList <Comparable> list) {
int end = list.size();
for (int i = 0 ; i < end; i++){
for (int j = end; j > 0; j--){
if ( list.get(j).compareTo(list.get(j-1)) > 0 ){
//swap
Comparable temp = list.get(j);
list.set(j,list.get(j - 1));
list.set(j - 1, temp);
//System.out.println(list);
}
}
end--;
}
}
The problem is, Java will then tell me it is out of bounds.
If I instead use
for (int j = end - 1; j > 0; j--)
the code will then run, however it does not run the number of times it needs to run for the list to completely finish sorting (aka it stops one loop ahead)
As explained, you need to start in end-1, or else you'll be accessing out of bounds of the array.
Let's say you have an array of integers: 5 1 4
Your algorith will do this:
1st iteration -> i = 0 / j starting at 2
1 5 4
2nd iteration -> i = 1 / j starting at 1
It will now only compare 5 and 1 and not switching them, because 5 is higher. So, and the 4 and 5? They should be swapped. Your algorithm implementation is wrong.
If you remove the end--; it should work.
However, this can be optimized
Use this code it will work for your requirement in array implementation where size is your array length.
for (int i = 0; i < size - 1; j++) {
for (int j = i + 1; j < size - 1; k++){
if (array[i] > array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
If the array is long 3, array[3] is out of bound.
Since you start with array[lenght] you have to decrement it before entering in the for cycle like the code you provide.
Using end - 1 will compare last and second last values in list
if you use end it will try to compare last value and value at index after last which will give ArrayOutOfBound Exception.
Now For correct output you have to remove end--; line as per shown below
for (int i = 0 ; i < end; i++){
for (int j = end -1; j > 0; j--){
if ( list.get(j).compareTo(list.get(j-1)) > 0 ){
//swap
Comparable temp = list.get(j);
list.set(j,list.get(j - 1));
list.set(j - 1, temp);
}
}
//remove below line
end--;
}
This will short the list by one value from right side also. So removing This will work

Categories