Java - for() loop and arrays - java

The next question is from test that I've done.. I've run the code on BlueJ and don't get why the return value is 5...
public int mystery(int[] myStuff, int num) {
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
myStuff = 2, 4, 0, 1, -6, 3, 8, 7, 5
num = 4
In the test I wrote - 0. Why 5? I don't get it!
What is the part of the
`return -1`
?

You're getting 5 because that is the index of the first element in the array whose value is less than 4 (when starting from the last element and working towards the first). Note that you have:
return k;
...where k is your array index. If you wanted to get the value at that index, you should do:
return myStuff[k];
Here's a simple example that shows that your result is in fact correct: http://ideone.com/7byIY
And the return -1; is just saying "if no elements are less than the specified number then return a value of -1 to indicate that no match was found". This is not an uncommon practice (returning an intentionally chosen, invalid value to indicate that there is no result).

It returns five because that's the index of 3 in your input array, which is the first number strictly smaller than 4 starting from the end of your array.
return -1; would be executed if none of the items in your array satisfy the "strictly smaller than num" criteria.

The function returns the largest index in the array corresponding to a value less than the target. This is accomplished on arbitrary arrays by scanning from the back and returning the first index corresponding to a value less than the target. In your example, 3 < 4 at index 5, so this is the correct answer. If no values smaller than the target are found, -1 is used as a sentinel value to indicate the algorithm failed to find a valid answer.

That function gives the position of the last number in the first argument that's smaller than the second argument (or -1 if all the numbers are larger than the second argument; -1 is a special value with no chance of ambiguity because there's no position -1).
That number is 3 and its position is 5 (starting with 0).

This function just searches for the last value in the array which is greater or equal than num. Let's compute the check myStuff[k] < 4 for all values:
0 1 2 3 4 5 6 7 8 // k
2 4 0 1 -6 3 8 7 5 // myStuff[k]
true false true true true true false false false // myStuff[k] < 4
The last index for which myStuff[k] < 4 is true is obviously 5, so that's the correct answer.
return -1 is needed so that the function returns a value, even if all elements of myStuff are larger than num. For example, with num = -99, the result would be -1.

your return-1 doesn't mean anything for the parameters you have passed here.
as the condition is true for value 3 so it returns the value of k, which is nothing but 5 bt that movement. this is because you are iterating backwards.

mystery(myStuff=[2,4,0,1,-6,3,8,7,5], 4)
then the for begins
for (int k = 8; k>=0; k--)
if ( myStuff[8]=5 < 4) - NO
2nd iteration
k = 7 if (7 < 4) - NO
... so on
k = 6 if (8 < 4) - NO
k = 5 if (3 < 4) - YES - so return k = 5
The last part means:
if myStuff does not have any value < num then it returns -1

Related

How to take find the value attached to a specific index of an array

I have to return the value for a specific index of an array.
I am to take the last digit in my array and use that digit as the index for where to look in my array. Meaning if my array is 6543743 I need to return the value at the 3rd index, which should be 4. I have this so far, but it keeps returning 3 - it's taking the final index instead of going to that index for the value.
x = array[array.length-1];
I'm clearly missing something, but I can't figure it out. Thank you!
You need to subset the array twice:
int[] array = { 6 5 4 3 7 4 3 };
int num = array[array[array.length - 1]];
The last value in the array is given by array[array.length - 1], and then this value is used as an index again into the same array.

Cannot understand Array bounds [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
I've been learning to code recently, but unfortunately iterating through arrays and understanding their Length property and not going out of bounds eludes me.
I have the following exercise that I need to solve in Java - input a few numbers, parse them and put them into an array then get the three largest numbers in it and print them in descending order. I managed to do it, but I did need to look up the last part, as I was getting ArrayIndexOutOfBoundsException. I have hardcoded the values in the Array, in order to try and understand it, but I'd appreciate some help on the matter.
Here is my solution:
int[] numbers = {1, 2, 3, 4, 5, 6};
Arrays.sort(numbers);
int count = Math.min(3, numbers.length);
for (int i = 0; i < count; i++) {
System.out.println(numbers[i + numbers.length - 1]);
What I am trying to do here is print them in ascending order, as printing them in descending will be numbers[numbers.length - 1 - i]. On my example I am getting OutOfBounds. If I do i + numbers.length - 3 it works.
Will someone be so kind as to explain why? I know it's a stupid question but I just can't seem to understand it.
Image that the array is like a chain of objects. You can always access any of those objects if you know its index. So in the case you have an array of length 9 that contains the first 9 positive integer you will have valid indexes through 0 to 8.
0 1 2 3 4 5 6 7 8
[1][2][3][4][5][6][7][8][9]
to print out the the values inside the array you could use:
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
}
and if you would like to backward print it then you should start from it's last index and decrement the i until it greater or equal to the starting index of the array:
for (int i = values.length - 1; i >= 0; i--) {
System.out.println(values[i]);
}
Whenever you try to access an index that is out of the bound of valid indexes it will result to IndexOutofboundsException. So if you like to invoke any arithmetics with calculating the indexes be aware of the fact that you have only few valid values for it.
So in this context let's look at it in terms of the minimum and maximum values that the array access can have
So for the minimum value of i (0), we get i + numbers.length - 1 = 0 + 6 - 1 = 5
and for the maximum of i we either get 3 or numbers.length:
In the case of 3: i + numbers.length - 1 = 3 + 6 - 1 = 8
In the case of numbers.length we get i + numbers.length - 1 = 6 + 6 - 1 = 12
You need to make sure that the possible values that the array will iterate between is always going to give a value within the bounds of the array (as clearly this does not)
Tried to run
for (int i = 0; i < count; i++) {
System.out.println(i + numbers.length - 1);
}
It prints:
5
6
7
Your array has 6 items and is indexed from 0 to 5. When you try to get item that has index >=6 it throws ArrayIndexOutOfBoundsException
If you want to print them in descending order use
System.out.println(numbers[numbers.length - 1 - i])

Why here I got different results?

I have next task: Given an array of ints, return true if the array contains no 1's and no 3's.
First version and it's right:
for (int i = 0; i < nums.length; i++){
if(nums[i] == 1 || nums[i] == 3)
return false;
}
return true;
but here's I got many wrong tests:
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 1 || nums[i] != 3)
return true;
}
return false;
Can you explain me reason why does it work like this? I supposed reason is something happened in second if(...)
The code should return true if there are no 1s and no 3s.
Let us take a look at your second code:
// Iterate all values
for (int i = 0; i < nums.length; i++) {
// Return true if value is not 1 OR not 3
if (nums[i] != 1 || nums[i] != 3)
return true;
}
// Return false
return false;
The key here is the condition val != 1 || val != 3 which is a tautology, i.e. it is true in all cases. Suppose a value of 5, it is not 1, so true is returned. Now suppose a value of 1, it is 1 but it is not 3, also true is returned.
You would need to substitute || by && which means and, which also better reflects your textual condition:
return true if the array contains no 1's and no 3's
However you can not directly return true if you found the first element which is not 1 and not 3. You first need to check all elements. However you can directly return false if you found the first 1 or 3. And that is exactly the first version of your code, which is correct.
Note that when negating a conditions you need to negate all quantifiers and operators too.
The first code realizes an approach using this logic:
Not (there exists one element which is 1 or 3)
¬(∃ e : e = 1 ∨ e = 3)
When now solving the negation you receive this logic:
All elements are not 1 and not 3
∀ e : e ≠ 1 ∧ e ≠ 3
So ∃ (exists) turns to ∀ (for all), = to ≠ and ∨ (or) to ∧ (and).
Why the first one works
It returns false if any item is not 1 or 3, and true if no items match
Why the second one does not work
It returns true all the time (if any item is not equal to 1 or 3, and no integer is equal to both 1 and 3), the only way to get false is to pass it an empty array.
You're implementing a short-circuit evaluation. The first version is right. In the second version, you prematurely return true when you encounter a number that isn't 1 or 3 - which is every number, since 1 is not 3 and vise versa.
For the second answer, you are using OR instead of AND. Hence whatever value you provide, it will always enter into the if condition.
Hope this helps.

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.

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