Variable not initialized in for loop - java

So I've been practicing my Java programming skills on the CodingBat website, when I came across this problem. In it, you have to make a simple method that takes in an array of integers of dynamic length, check to see if the elements in the array are in increasing order (1, 2, 3, 15678, etc), and return "true" if true, or "false" if there is an integer out of order.
Firstly, I initialize a boolean variable named "result". Then, I iterate through the array of integers passed by the method. If the current index value is less than the next index value, I set "result" to "true", and repeat the loop. Else, I'll set "result" to "false", break out of the loop and set "result" to "false". After the FOR loop, I return "result".
However, I've been receiving an error message that "result" has not been initialized properly. I can kinda understand the confusing with the JVM, however I thought that setting the value for "result" inside of the IF/ELSE statements would solve that.
Here is a copy of the code that I have done so far:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length; i++) {
if (i < (i + 1)) {
result = true;
}
else {
result = false;
break;
}
}
return result;
}

First of all, i < i+1 will always be true, unless i = Integer.maxValue, in which case you'll wrap around to Integer.minValue.
What you want is scores[i] < scores[i+1] , and you'll need to adjust your loop values to avoid an index out of bounds on the last iteration.
So, your code fixed:
public boolean scoresIncreasing(int[] scores) {
boolean result;
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] < scores[(i + 1)]) {
result = true;
}
else {
result = false;
break;
}
} // missing brace
return result;
}
Try this as an alternative. It works on the principle that once you get a false, you can get out immediately.
public boolean scoresIncreasing(int[] scores) {
boolean result = true; // assume true
for (int i = 0; i < scores.length-1; i++) // fix loop end
{
if (scores[i] > scores[(i + 1)]) return false;
} // missing brace
return result;
}
Of course, you may want to introduce bounds checking at the beginning to ensure that there are at least two values.

You are simply missing a closing brace (}) before return result.
As a suggestion to simplify the code (and deal with arrays of 0 elements!), you may want to initialize result to true. Then, as you loop over the array, change result to false if and only if you find an element out of order.
One other word of caution. You use element i + 1 in your for loop. Think about what will happen when you get the last element in the array (i == scores.length - 1).

if (i < (i + 1)) will always evaluate to true. You need to compare the contents of the array at those indexes, not the indexes themselves.
Something like:
public boolean scoresIncreasing(int[] scores) {
for(int i = 0; i < scores.length-1; i++) {
if(scores[i] > scores[i+1]) return false;
}
return true;
}

What if scores has 0 elements? ;]

in your code, you are returning result inside the for loop (after the if-else statement).
Add another bracket before the return statement (to close the for loop)

Related

While finding elements on an array when should I make an else?

I am using a while loop with a counter to find an element on an array. I will check that if the returned element is equal to the lenght of the array the element is not found. The loop is like this.
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
else{
i++;
}
return i
What I am wondering if it would be better instead of doing an else on every condition to do the following
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
i++;
}
if(!found)
i++;
return i-1
I feel that the second one is more efficient because it doesn't have to check the condition on every loop and in case that the array was really long it would have to be done a lot. But I'm not sure on when to decide each because the second looks realy ugly and not intuitive.
There are multiple possible refactoring that avoid the question, but I'll try to answer your question as is :
the else costs nothing : it's just a block that will be executed if and only if the if's condition evaluates to false.
it is easily understood by anyone
Even if it doesn't look the prettiest, I see no reason to avoid it. In your second code, not only do you introduce extra instructions, it is also harder to understand since you have to get why the index needs to be increased when the element isn't found.
extract the code in a method, like this
public int contains(....) {
int i = -1;
while(i < words.length){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
return i;
}
i++;
}
return i;
}
no need for additional variables and clearer structure of the code
I don't think that you need to use an else part or another if condition to check whether its found or not cause you are already checking the condition in while loop.
int i = 0;
int returned;
boolean found = false;
while(i < words.length && !found){
WordInText check = new WordInText(w);
if(check.equals(words[i])){
found = true;
}
i++;
}
return i;
So here the loop will go on until the value of found becomes true (means that till the required element is found. Then in next iteration it will check whether the found value is false. As it's not false anymore the loop will not be executed and the i will be returned.
There you can check the value of i and decide whether the element is found or not.

Why no out of bounds error on for loop (Java)

I'm doing a problem on codingbat.com and am confused with why this solution to the problem does not give an index out of bounds error. Wouldn't the first for loop search for an index that is beyond the length of the passed array?
Here's the problem:
We'll say that a value is "everywhere" in an array if for every pair of adjacent elements in the array, at least one of the pair is that value. Return true if the given value is everywhere in the array.
Here's my working solution:
public boolean isEverywhere(int[] nums, int val) {
boolean flag1 = true;
boolean flag2 = true;
for (int i = 0; i < nums.length; i += 2) {
if (nums[i] != val) flag1 = false;
}
for (int i = 0; i < nums.length - 1; i += 2) {
if (nums[i + 1] != val) flag2 = false;
}
return flag1 || flag2;
}
Thanks!
No. The test happens after i is incremented. So, once i is not less than the length of the nums array the loop stops. The second loop uses i + 1 at if (nums[i + 1] != val) which is why it needs to test that i is less than the length minus one.
Also you can make the method static (since it uses no instance state).
It wouldn't because while i += 2 is written after i < nums.length, the loop still checks that i is less than the given length(nums.length) before going onto the body of the loop even after 2 has been added on.

View if a word's letters are in ascending order

I've been at this for a while, but as the title says, I'm trying to create a method that will compare each letter to the letter after it and see if the word is ascending. The method should then return a boolean value. But when it's implemented in my code, it will fail with:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(Unknown Source)
and multiple other lines of error code.
Here's my source code:
public static boolean ascending(String word){
int i = 0;
boolean ascend;
do {
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
} while (i <= word.length());
i = 0;
return (ascend);
}
I can't see where I'm going wrong?
condition should be
i < word.length()-1
and the i = 0; at the end should be in side the loop as i++, else it will be infinite loop.
also, you have actually put the reverse check. once you fix ArrayIndexOutOfBoundsException you will return false for ascending string and true otherwise
public static boolean ascending(String word){
if(word == null || word.length <2) return false;
int i = 0;
boolean ascend = false;
while(i < word.length()-1){
if (word.charAt(i) <= word.charAt(i+1))
ascend = true;
else{
ascend = false;
break;
}
i++;
}
return (ascend);
}
In pseudo code:
take the first letter (F) => store it
take the next letter (N) => check against first => stop here if not OK
is there another next letter => stop here if not
update first letter (F) with next letter (N)
repeat starting from 2
Few things needs to be fixed here:
You need to increment "i" to traverse through the word.
Restrict your while loop till (i < word.length() )
You may break at any point when you find ascend is false. No need to continue with the looping.
I would not use a do while because there is an opportunity to run this on an empty string causing it to crash. I would instead use a regular while and at the beginning test for while (i < word.length()-1). You never want to test past the end of the string. You always want to check to see for a string length of n that charAt(n-1) < charAt(n). Also I don't see an incrementer to increase the value of i. Loop will never continue on to the next letter and will run forever.
public static boolean ascending(String word){
int i = 0;
boolean ascend;
while (i < word.length()-1)
{
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
i++;
}
i = 0;
return (ascend);
}
Do not use do-while loop. Even if you do you need to run some checks beforehand to make sure your word has length more than 1 otherwise your code will raise an IndexOutOfBounds Exception. If you insist on using it, change your condition to i
Here is a working code example:
public boolean isAscending(String word){
if (word==null || word.length==0){
return false;
}
for (int i=1; i<word.length(); i++){
if (word.charAt(i) < word.charAt(i-1))
return false;
}
return true;
}

How to check an entire array?

I want my program to check whether every element in the entire int[] array is non-zero.
What I currently have:
for(int i=0; i<myArray.length; i++)
{
if(myArray[i] == 0)
{
completed = false;
}
else
{
completed = true;
}
}
But the loop keeps doing else statement, if only one array in the middle is non-zero and won't check the rest of the array.
You need to have it break out of the for loop once you've found a 0:
if(myArray[i] == 0)
{
completed = false;
break;
}
This way, if you find a non-0 element later, you won't falsely set completed back to true.
You can use a break statement to break the loop on first occurrence of a zero value as:
boolean completed = true;
for(int i=0; i<myArray.length; i++) {
if(myArray[i] == 0) {
completed = false;
break;
}
}
if(!completed){
//array has zero values
}
Other important pointers:
Arrays.binarySearch(): works only on sorted array so not useful in your case.
Searches the specified array of bytes for the specified value using the binary search algorithm. The array must be sorted (as by the sort(byte[]) method) prior to making this call. If it is not sorted, the results are undefined. If the array contains multiple elements with the specified value, there is no guarantee which one will be found.
indexOf method internally does the same loop and comparison. So I don't see much difference in your original pattern and new syntax. Though it may make your code look compact.
You can put break; statement after finding the first 0 element, so that it will jump out the loop.
There is no need to loop through each elements: JSBIN Demo
Use IndexOf();
var myArray = [1,2,1,3];
var completed = myArray.indexOf(0) != -1
Alternately, you could do
var completed = true;
for(int i=0; i<myArray.length; i++)
{
if(myArray[i] == 0)
{
completed = false;
}
}
Which would do the same.

(Java) Check array for increasing elements

I'm attempting to create a method that checks an array for increasing elements. True should be returned if all the elements are in increasing order. I get an out-of-bounds exception when I compare arr[i+1]. Any ideas on how I can make it work.
int[] one = {1,2,3,4,5};
public static boolean isIncreasing(int[]arr)
{
boolean z = false;
for(int i=0; i<arr.length;i++)
{
if(arr[i]<arr[i+1])
{
z = true;
}
}
return z;
}
Because in a list with n items there are only n-1 gaps between them.
Change to
for (int i=0; i<arr.length-1; i++)
(Also you might want to check whether starting with false and setting to true is the right way around).
You have two problems:
Your loop is one iteration too long: Because you are checking element i+1, i needs to finished incrementing one iteration earlier than a usual loop.
Your logic is flawed. Your loop will terminate the first time the check is true, so this array will pass: {1, 2, 0} when tested the first iteration tests 1 < 2 which is true, so return true - this is not what we want)
Fixing these two problems:
int[] one = {1,2,3,4,5};
public static boolean isIncreasing(int[] arr) {
for(int i=0 ; i < arr.length - 1; i++) { // finish at length - 1
if (arr[i] > arr[i+1]) {
return false; // found elements that are out of order - return false
}
}
return true; // nothing out of order found - return true
}
This kind of logic - with an early exit with false on problem and a final return of true - is very common and a good pattern to learn.
I suggest you write your method like this
public static boolean isIncreasing(int[]arr)
{
for(int i=1; i<arr.length;i++)
{
if(arr[i-1]>arr[i])
return false;
}
return true;
}
it will help
return the proper result (yours returns true when it should not)
consider out of bounds
avoid unnecessary looping
You get that exception as when (i+1)'s value becomes array.length. For example if you have an array of length 10, the elements indexes will be from 0,1,2...till 9. so either you have to check till i < arr.length - 1 or you can modify your logic accordingly.
You can use Java 8's IntStream.
import java.util.stream.IntStream;
public class Test {
public static boolean isIncreasing(int[] a) {
return IntStream.range(1, a.length).reduce(0, (acc, e) -> acc + (a[e - 1] <= a[e] ? 0 : 1)) == 0;
}
}

Categories

Resources