Reversing elements in array - java

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.

Related

Replacing elements in array by the larger of its neighbour

I'm currently stuck on this one assignment where I don't know if I got the instructions wrong, or if the code is as it should be. The instructions is:
Replace each element except the first and last by the larger of its two neighbors.
I've completed the code, but the one problem I have is that the last element is being replaced even though it shouldn't. It'd very nice if you could take a look at my code.
public static void replaceWithNeighbours(int[] array) {
for (int i = 1; i < array.length - 1; i++) {
int larger = array[i - 1];
if (larger < array[i + 1]) {
larger = array[i + 1];
}
array[i] = larger;
}
}
A naive solution, the array management can be done better, however this works.
public static void replaceWithNeighbours(int[] array, int[] out) throws Exception
{
// checkif lengths match
if (array.length != out.length)
{
throw new Exception("Lengths don't match");
}
// replace values in output array
out[0] = array[0];
out[out.length - 1] = array[array.length - 1];
for (int i = 1; i < array.length - 1; i++) {
int larger = array[i - 1];
if (larger < array[i + 1]) {
larger = array[i + 1];
}
out[i] = larger;
}
}
Your main problem is that you iterate over the array and update it, however do not consider previous iterations. This means you can look at a neighbor who already holds an updated value and use this value, because the old is overwritten.
Since you also have a problem with the last element being updated:
Go through your code using the debugger or simple print statements and find out where exactly your index 9 is actually accessed. It is not in replaceWithNeighbours, so must be somewhere else. You can solve this by yourself however, just look what indices are used and when you see a 9, look for what is entered and where.
This can be done in a simple way:
public int[] replaceWithNeighbours(int[] arr) {
int[] ret = new int[arr.length];
for (int i = 0; i < arr.length; ++i) {
if (i == 0 || i == arr.length - 1) {
ret[i] = arr[i];
} else {
ret[i] = Math.max(arr[i-1], arr[i+1]);
}
}
return ret;
}
A short explanation: first we create a new array ret which will hold desired result and set it to the same length as original array. Then we loop over contents of original array. If we're dealing with first or last element we just copy them to ret. If we're dealing with other elements, we use Java's Math.max method to determine maximum value of 2 neighbours and set i-th element in ret to that value.

Understanding the logic of an add to an array method

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;
}
}

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);
}

writing pseudocode for my algorithm

I have implemented counting sort and I am struggling to write pseudocode for the last step of my algorithm.
My code is as follows:
public int[] countingSort(int[]array) {
int[] aux = new int[array.length];
// find the smallest and the largest value
int min = array[0];
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] < min) min = array[i];
else if (array[i] > max) max = array[i];
}
// init array of frequencies
int[] counts = new int[max - min + 1];
// init the frequencies
for (int i = 0; i < array.length; i++) {
counts[array[i] - min]++;
}
// recalculate the array - create the array of occurences
counts[0]--;
for (int i = 1; i < counts.length; i++) {
counts[i] = counts[i] + counts[i-1];
}
// Sort the array right to the left
// 1) look up in the array of occurences the last occurence of the given value
// 2) place it into the sorted array
// 3) decrement the index of the last occurence of the given value
// 4) continue with the previous value of the input array (goto: 1), terminate if all values were already sorted
for (int i = array.length - 1; i >= 0; i--) {
aux[counts[array[i] - min]--] = array[i];
}
return aux;
}
My psuedocode is as follows:
Procedure: Counting Sort
Input: Array (A)
Steps:
Work out the min and max in the arrray
DECLARE MIN AS first element in A
DECLARE MAX AS MIN
LOOP through elements in A
IF the current element is less than MIN
SET MIN to current element
ELSE IF the current element is greater than MAX
SET MAX to current element
Initialise the array of frequencies
DECLARE array C (counts) of size (MAX - MIN + 1)
COUNT the frequency of each element
LOOP through elements in A
C[array[i]-min] increase by 1
Recalculate the array - Create the array of occurences
Decrement C[0] by 1
LOOP through elements in C
C[i] = C[i] - C[i-1]
Sorting the arrays
Look up in the array of occurences the last occurence of the given value
LOOP through elements in the array of occurences
Place it into the sorted array
Decrement the index of the last occurence of the given value
Continue with the previous value of the input array (goto: 1), terminate if all values were already sorted

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