java bubble sort issue - java

I am learning Java from the past one month. I am having difficulties to understand the line
for(int i = 0;i<list.length-1;i++){
Can anybody explain me in layman lang. I am a slow learner. I understand for loop but this thing i am not able to understand
Int[]list = {5͵7͵54͵34͵87͵44};
boolean swap = true;
int temp;
while(swap){
swap = false;
for(int i = 0;i<list.length-1;i++){
if(list[i] > list[i+1]){
temp = list[i];
list[i] = list[i+1];
list[i+1] = temp;
swap = true;
}
}
}

Let's consider an array
0 1 2 3 4 5 6 7 8 9 <-- array indexes
_ _ _ _ _ _ _ _ _ _
| | | | | | | | | | |
The line for(int i = 0;i<list.length-1;i++){ tells you you are going to iterate from 0 to lenght - 2. In my example the length is 10, so you're going to iterate from 0 to 8.
The reason for it is to avoid OutOfBoundsException in this line list[i] > list[i+1] where you compare i-th index with i+1-th index. In the last iteration it's going to be i = 8 and i + 1 = 9 (which is the last index of my array).

your code is going through all list.entries in this for loop.
if your list.entry at position i is bigger than list.entry at position i+1
you save your list.entry at position i in temp
then you are saving the bigger list.entry at position i+1 in your actual list at position i.
your list[i+1] is getting the smaller value of temp (which you saved in the beginning)
after that you set swap = true... probably in order to know that you swapped i and i + 1
if swap is not true your while loop is done, because your list is sorted

the loop at line 5 is for comparing all possible pairs of numbers. The while loop is for selecting first member and the for loop is for selecting second member.

You have an array of size 6 i.e from index 0-5. Your for loop starts with the index 0 and checks the element at index 0 with index 1. If index 0 is greater than index 1, swap the two values. Similarly, it checks till index 4(i=4) and index 5(i+1) is reached, because this will be the end of the array index i.e you will check for the last two elements in the array(since the array index starts from 0). If you go any beyond i=4, you will check for 5 and 6(which does not exist in your array and will throw an OutOfBoundsException).

for(int i = 0;i<list.length-1;i++){
goes through items in list. You are accessing each item with list[i]. (the first item has index 0 (list[0]). i is going to be zero (0) on the beginning of your loop and then it is going to increase by one (i++) each iteration; It will increase until the middle expression
i<list.length-1`)
fitting i.
So in your case it will go through the items (you have 6 in your list as you can see). The last item has index 5 list[5]. That is why you have -1 in list.length-1

Related

Java: delete/pack method, can someone explain?

Can someone explain to me how this method works? I don't understand how they move in the array to delete the item index.
private void pack(int index) {.
for(int i =index; i<noOfItems-1; i++)
theItems[i]=theItems[i+1];
noOfItems--;
}
It simply shifts all elements, starting from the given index, one position up.
After that, it decreases the number of elements in the array.
For instance, calling the method with parameter 4, the value of the element with index 5 is moved to the element with index 4. The one on index 6 is moved to index 5, etc.
So, if you first had array
45, 78, 1, 45, 234, 856, 4323, 87, afterwards you have
45, 78, 1, 45, 856, 4323, 87
They are writing the next value of the array into it and decreased the array size.
For example,
int a[] = new int[] {1,2,3,4,5}
if I call pack(2) then the output of printing a is
{1,2,4,5,5}
I don't understand how they move in the array to delete the item index.
They don't. Java arrays are of fixed size, so the code simply copies all items starting at index up to noOfItems left by one element, and then records the fact that the number of items the array holds has reduced by one.
Here is an example: let's say that you start with this ten-element array
0 1 2 3 4 5 6 7 8 9
A B C D E F G H _ _
^
|
last item
Now you wish to delete the item at index 4. The algorithm would transform the array as follows:
0 1 2 3 4 5 6 7 8 9
A B C D F G H H _ _
^
|
last item
Note that the item at index 7 got copied, but did not get deleted. Its content does not really matter, because it's past the position of last item (i.e. noOfItems).
There are situations when this would be problematic - specifically, when you have large objects in the "dead" portion of the array, they may "linger" past the time when they should become eligible for garbage collection.
Beginning with index each value is shifted by one to the beginning of the array.
theItem[index] = theItem[index+1];
theItem[index+1] = theItem[index+2];
Because the value at index is never written to a new location, it is no longer accessible.
At the end the noOfItems is decremented by one because now there are one fewer elements in the array.
On the array [1,2,3,4,5,6] with noOfItems = 6 and calling pack(4) the following would happen:
[1,2,3,5,5,6]
[1,2,3,5,6,6]
noOfItems = 5
The last 6 in the array is not gone, but since every other bit of code (I guess) is using noOfItems to calc the end of the array it is no longer seen.

Duplicate for-loop practice, beginner needs advice to study

Understanding the -1 in the for loop, need detailed explanation with for and if lines of code included?
int[] array = { 2, 5, 1, 2, 3, 5 };
Arrays.sort(array);
// why does this start counting from 1, and if l put 0 it goes to error, out of bounds?
for (int i = 1; i < array.length; i++) {
if (array[i] == array[i - 1]) { // - 1?
System.out.print(array[i]);
}
}
There is nothing inherently wrong with it.
It just makes the iteration to start with i=1 up to the array's length, but since indexing in arrays are zero-based you have to offset it when getting the value.
That is why is array[i-1]
If you put i=0 then you also have to change the ending condition to array.length-1, and you have to access the values by array[i] in order to avoid going out of bounds.
For questions like this, take the code one line at a time and try to follow what it is doing.
The first thing you do here is to create an array, then sort it. After the Arrays.sort(array) call, your array will contain the following:
index 0 1 2 3 4 5
----------------------
contents 1 2 2 3 5 5
Remember, arrays are zero-indexed - that means the very first element is located at index 0. (The contents of the array don't matter, it's the index you want to pay attention to.)
Arrays cannot have indexes less then zero, and they also cannot have indexes greater than their length-1. So, for your example, that means you cannot use -1 as an index because it is less than 0. You also cannot use 6 as an index, since 6 is greater than the length of the array (6) minus one.
In the initialization of the for-loop, you set i equal to 1 for the first iteration. Though unconventional, it's perfectly legal. This simply represents which index we will start from in the array. So for the first iteration of the loop, array[i] will be pointing to the value 2, and array[i-1] points to the value 1.
index 0 1 2 3 4 5
----------------------
contents 1 2 2 3 5 5
i ^
i-1 ^
Now, what if you set i to start at index 0 instead? Well, then array[i] will point to the 0th index (value 1)... but what does array[i-1] point to?
index 0 1 2 3 4 5
----------------------
contents 1 2 2 3 5 5
i ^
i-1 ^
It's pointing to index -1. Since arrays can't have indexes of -1, this is causing your IndexOutOfBoundsException. Hopefully that makes sense.

Recursion with an Array

I'm having a bit of trouble understanding the concept of recursion. I understand that it is basically a method that calls itself and turns a big problem into a bunch of smaller parts to solve it. What I'm having difficulty with is using recursion with an array. Here is an example in my book:
//Precondition: x is an array of n integers
public int recur(int[] x, int n)
{
int t;
if(n == 1)
return x[0];
else
{
t = recur(x, n-1);
if(x[n-1] > t)
return x[n-1];
else
return t;
}
}
If anyone has the time, could you explain what this method does and how it works? Greatly appreciated!
This function returns the largest integer of an integer array.
Lets see how, Your function recur takes an integer array x and its length n.
If the length of array is 1 then the lone element x[0] is the largest one.
Else we get the largest element from the array starting with x[0] to x[n-2](that is array of length n - 1) and so on, when we get the largest element we keep on sending it as the return value till recursion finishes, finally returning the largest value.
This method finds the biggest number among the first n elements of an array.
It works by finding the biggest number among the first n-1 elements; then checking whether the nth element is bigger. The recursion comes in when it finds the biggest number in the first n-1 elements - it does that by calling itself with n-1 in place of n.
Of course, if n is 1, then there's nothing to check - we should just return the first element. This is the "base case" of the recursion.
Note that when I say the nth element, this is actually x[n-1], not x[n] because array indexes start from zero.
In recursion we have what is called base case which is a condition to make the recursion stop. In this situation the base case is if (n==1) where the first element of x[] is returned.
Let's go to the second part of the recursion. The function is calling itself but decrementing n, until it reachs to the base case. Once the base case is returned, the function will compare the first element, now t, with the next one x[n-1] (where n is equal to 2) and return the greater of both. When one value is returned the function goes to its previous call in the stack.
In other words, to analize recursion you should go through the function calls until the base case is reached and once there, start to go back leaded by the returns or the final execution of the function.
As stated in above answers this method will return largest among the first n values in the array, i would like to show this answer pictorially
Assume array with values
{5, 4, 2, 1, 8, 6, 4, 2, 12, 33}
-----------------------------------------------------------------------------------
caller | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
===================================================================================
t | 12 | 8 | 8 | 8 | 8 | 5 | 5 | 5 | 5 | none
===================================================================================
return | 33 | 12 | 8 | 8 | 8 | 8 | 5 | 5 | 5 | 5
Here caller is the invoker of recursive method. and in the n = 10, 33 will be compared with 12 and 33 will be returned to invoker. Hence invoker will received largest value in the array.

Why ArrayList giving unordered output?

I have written java program, to add integer in ArrayList and remove that integer from ArrayList . but it not giving me proper result. here is my code..
public static void main(String args[])
{
ArrayList<Integer> a=new ArrayList<Integer>();
a.add(6);
a.add(7);
a.add(8);
a.add(9);
for(int i=0;i<=a.size();i++)
{
System.out.println("Removed Elements=>"+a.remove(i));
}
}
it giving me output as follows
Removed Elements=>6
Removed Elements=>8
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at CollectionTemp.main(CollectionTemp.java:19)
why i am getting output like this?
Your array:
a[0]=6
a[1]=7 <-- i
a[2]=8
a[3]=9
Then you remove at 1, and i increments to 2:
a[0]=6
a[1]=8
a[2]=9 <-- i
Remember that array indexes start at 0, so the last element is at a.length - 1
You get your exception because the loop condition i <= a.size(), so at the final iteration:
a[0] = 7
a[1] = 9
2 <-- i
When you remove items from a list, or any collection, you either use the iterator, or you use a reverse loop like this.
for (int i = (a.size() - 1); i >= 0; i--) {
System.out.println("Removed Elements=>" + a.remove(i));
}
By going backwards, you avoid the incrementing by 2 problem that has been documented in the other answers.
for first iteration, a.remove(i) causes the element 7 to be removed which is returned by remove method.
For second iteration, the size of list is 3 and you are removing the element at index 2 which is 9. SO remove method returns 9.
In short
Iteration | Size of list | index being removed | element removed
----------+--------------+---------------------+----------------
1 | 4 | 1 | 7
2 | 3 | 2 | 9
If you want a forward loop to remove all elements you could use the following code:
while(!a.isEmpty())
{
System.out.println("Removed Elements=>" + a.remove(0));
}
Your problem is that, as you remove elements, you resize the ArrayList. However, your loop counter is not updated, so you iterate past the bounds of the ArrayList.
ArrayList.remove(index) removes the element from the array, not just the contents of the ArrayList, but it actually resizes your ArrayList as you remove items.
First you remove the 1st element of the ArrayList.
Removed Elements=>6
Here the list has been resized from size 4 to size three. Now the element at index 0 is 7.
Next, you step to the element at index 1. This is the number 8.
Removed Elements=>8
Here the ArrayList has been resized to length 2. So there are only elements at index 0 and 1.
Next you step to index 2.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at CollectionTemp.main(CollectionTemp.java:19)
There is no index 2, so you get an IndexOutOfBoundsException.
the index starts with 0 and ends with size - 1
your loop goes from 1 to size - 2
ArrayList indexes start at zero, but your loop starts removing at 1. After adding the elements your arraylist looks like this:
0 - 6
1 - 7
2 - 8
3 - 9
Because your loop starts counting at 1, you will first remove the element labeled 1, which is 7.
The list will then look like this:
0 - 6
1 - 8
2 - 9
Then the loop will remove the element labeled 2, which is now 9.
So the two mistakes are starting at 1 instead of 0, and incrementing the counter after something has been removed (all elements after the removed element will shift down).
In the first iteration , i starts from 1, so your second element is removed ie. 7. Now list has
6
8
9
Next iteration is 2, so third element 9 is removed.
Your output is correct : Here is the explaination.
When the loop is executed for the first time, value of i will be 1. and it execute the statement a.remove(1). after removing the value 7 which is at place a[1], '8will be ata[1]'s place. After that i is incremented and becomes 2 and it removes the element a[2] which is 9.
This is simple logic:
First Iteration i=1:
a[0]=6,
a[1]=7,
a[2]=8;
a[3]=9;
Remove a[i] i.e a[1] removes 7
Second Iteration i=2:
a[0]=6
a[1]=7
a[2]=9
Remove a[i] removes 9
The value of i in the loop goes through the following values
0
1
2
3
4
The array has index with values 0 , 1 , 2 , 3
The loop will run for values 0,1,2,3,4
The array is not displayed ordered bcoz when one value is removed the next value is available at index 0
At i=2 , the size of array is 2 and max index is 1 , and hence IndexOutofBound exception is encountered
use the following loop :
while(a.size()>0)
{
System.out.println("Removed Elements=>"+a.remove(0));
}
whenever you remove an element from arraylist it deletes element at specified location.and this should be noted each time the size of arraylist decreases.
I dont understand what are you trying to remove. If you wan to clear list just call clear() method. If you are trying to remove objects contained in list, than you should know that ArrayList contains objects, not primitive ints. When you add them your are doing the following:
a.add(Integer.valueOf(6));
And there are two remove methods in ArrayList:
remove(Object o) //Removes the first occurrence of the specified element from this list
and the one you are calling:
remove(int index) //Removes the element at the specified position in this list
May be you should call first one:
a.remove(Integer.valueOf(i));

Looking for a hint (not the answer) on how to return the longest acsending non contiguous substring when I already have the length

My code currently returns the length of the largest substring:
for(int i = 1; i<=l-1;i++)
{
counter = 1;
for(int j = 0; j<i;j++)
{
if(seq[j]<seq[j+1])
{
count[j] = counter++;
}
}
}
for(int i = 0;i<l-1;i++)
{
if(largest < count[i+1])
{
largest = count[i+1];
}
}
assuming seq is the numbers in the sequence. So if the sequence is: 5;3;4;8;6;7, it prints out 4. However, I would like it to also print out 3;4;6;7 which is the longest subsisting in ascending order.
I am trying to get the length of the largest sub sequence itself and the actual sequence, but I already have length..
My instinct is to store each number in the array, while it is working out the count, with the count. So returning the longest count, can also return the array attatched to it. I think this can be done with hashtables, but I'm not sure how to use those.
I am just looking for a hint, not the answer.
Thanks
You need to implement a dynamic programming algorithm for the longest ascending subsequence. The idea is to store a pair of values for each position i:
The length of the longest ascending subsequence that ends at position i
The index of the item preceding the current one in such ascending subsequence, or -1 if all prior numbers are greater than or equal to the current one.
You can easily build both these arrays by setting the first pair to {Length=1, Prior=-1}, walking the array in ascending order, and looking for the "best" predecessor for the current item at index i. The predecessor must fit these two conditions:
It must have lower index and be smaller than the item at i, and
It must end an ascending subsequence of length greater than the one that you have found so far.
Here is how the data would look for your sequence:
Index: 0 1 2 3 4 5
Value: 5 3 4 8 6 7
------------ ----------------
Length: 1 1 2 3 3 4
Predecessor: -1 -1 1 2 2 4
Once you finish the run, find the max value among lengths array, and chain it back to the beginning using the predecessor's indexes until you hit -1.

Categories