Return false; statement doesn't "return" - java

My return false statement doesn't work as expected. I have a recursive method called "prosegui", it works with most of the words i want to work with, but with a few of them the return false doesn't return the value "false" as it should but continue and end up returning true.
if (contChar < this.parola.length() - 1) {
if (this.parola.charAt(contChar+1)==matrice[i][j])
{
prosegui(proseguiI,proseguiJ,i,j,contChar+1);
}
else
{
System.out.println("FALSE");
return false;
}
}
System.out.println("TRUE");
return true;
I really don't know how to sort it out.
EDIT:
the program print both "FALSE" and then "TRUE"
EDIT:
public boolean prosegui(int i, int j, int proseguiI, int proseguiJ, int contChar)
{
if (contChar < this.parola.length() - 1)
{
int direzioneI=proseguiI-i;
int direzioneJ=proseguiJ-j;
i=proseguiI+direzioneI;
j=proseguiJ+direzioneJ;
int cont;
StringTokenizer st = new StringTokenizer(this.results);
cont=0;
char[][] matrice = new char[this.lung][this.lung];
while (st.hasMoreTokens())
{
matrice[cont]=st.nextElement().toString().toCharArray();
cont++;
}
if(this.parola.charAt(contChar+1)==matrice[i][j]){
prosegui(proseguiI,proseguiJ,i,j,contChar+1);
}
else
{
System.out.println("FALSE");
return false;
}
}
System.out.println("TRUE");
return true;
}

your function cannot return false when entering prosegui(...) recursivly, because you don't check the result of your recursive call, it will always return true.

First time through, this.parola.charAt(contChar+1)==matrice[i][j] is true. This means that prosegui is called again with a different input (prosegui(proseguiI,proseguiJ,i,j,contChar+1)).
This time through this.parola.charAt(contChar+1)==matrice[i][j] is false. This means that "FALSE" will be printed, and false will be returned.
Now we are back at the call to prosegui(proseguiI,proseguiJ,i,j,contChar+1). If we step forward from here, "TRUE" is printed and true is returned.
That's my theory anyway! Hope that helps.

If this code is in the prosegui method, then when it calls itself here:
prosegui(proseguiI,proseguiJ,i,j,contChar+1);
The true/false returned by this call is never used.

Related

For if loop wont loop: any pointers to why that might be?

This is supposed to loop 24 times; it does not, and I'm pretty confused as to why. Please help me various Kenobis out there :
private boolean simpleMove(Board bd)
{
int b = rn.nextInt(3);
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
System.out.println(i);
return true;
}
else {
System.out.println(i);
}
}
System.out.println("invalid");
return false;
As the comments point out your loop will execute a maximum of 24 times.
But the return statement inside the if statement may cause it to return 'early'.
It looks like it's some kind of board game thing.
The board appears to have 24 'squares' and it makes the first legal move and returns true.
If it fails to find a legal move, it returns false.
I can't confirm the logic overall but that rationale seems sound:
If there's a move available, take it and return true.
If no move is available, make no move and return false.
If you expected it to continue, even after finding a "valid" move, then simply store the fact that a valid move has been found. This can be done in a separate boolean variable:
private boolean simpleMove(Board bd) {
int b = rn.nextInt(3);
boolean valid = false; // until proven otherwise below
for (int i = 0; i < 24; i++) {
if (bd.isVacant(i) && rul.isLegalMove(tigerLocs[b], i)) {
bd.swap(tigerLocs[b],i);
bd.setTiger(i);
tigerLocs[b] = i;
valid = true;
}
System.out.println(i); // why output HERE when we have a return value?
}
if (!valid) {
System.out.println("invalid"); // why output HERE when we have a return value?
}
return valid;
}
It's unclear if multiple "valid" moves could be found, and whether that would be a problem when you "swap" or not. If there is only ever one possible move, then there would be no need to continue iterating with the for loop; simply return in the body like you were doing.

Checking if a string contains only digits and then setting it only if it doesn't contain characters other than digits

/**
* Set the person's mobile phone number
*/
public void setMobile(String mobile) {
for (int i = 0; i < mobile.length(); i++) {
if (!Character.isDigit(mobile.charAt(i))) {}
}
this.mobile = mobile;
}
So I basically need to make sure the string only contains digits, and if it contains non-digits for the method just to do nothing.
The problem I have is that if there is a random character in a string of numbers i.e. "034343a45645" it will still set the method.
Any help is appreciated thanks!
You could use String.matches(String regex):
boolean onlyDigits = mobile.matches("[0-9]+");
With a for loop you can just break when a non-digits is found.
boolean onlyDigits = true;
for (int i = 0; i < mobile.length(); i++) {
if (!Character.isDigit(mobile.charAt(i))) {
onlyDigits = false;
break;
}
}
Instead of breaking out of the loop, you could also just return. As it sounds like you don't want anything else to happen after. Thus eliminating the need for the onlyDigits variable to begin with.
Note that if mobile.length() == 0 then onlyDigits would still be true in relation to the above for loop. So assuming onlyDigits should be false if mobile is an empty string, then you could initialize it as such:
boolean onlyDigits = !mobile.isEmpty()
After checking you can then assign it if onlyDigits is true.
if (onlyDigits)
this.mobile = mobile;
You have two problems:
First: you didn't exit the loop if the if condition is false
Second: why using loop try implement tryParse like this
boolean tryParseInt(String value) {
try {
Integer.parseInt(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
if(tryParseInt(mobile)){
this.mobile = mobile;
}
add a boolean letterFound;
then at your for loop
whenever a letter is found use your else statement to set letterFound to true
then immediately stop the loop i=mobile.length() at your else statement

Which one is better, conditional for loop or for loop with a break (for short block of code)?

I am trying to find out which practices make your code more readable, specifically when your block of the code is short. Please look at these two versions of the for loop and let me know which one is more readable;
private boolean isValid(String guessInput)
{
boolean result = true;
for (int i = 0; i < guessInput.length(); i++)
{
if (!Character.isDigit(guessInput.charAt(i)))
{
result = false;
break;
}
}if (result)
{
int guessInputInt = Integer.parseInt(guessInput);
if (guessInputInt >= minGuess && guessInputInt < maxGuess)
guesses.add(guessInput);
else
result = false;
}else
System.out.println("Your input is not valid.");
return result;
}
Version 2
private boolean isValid(String guessInput)
{
boolean result = true;
for (int i = 0; i < guessInput.length() && result; i++)
{
if (!Character.isDigit(guessInput.charAt(i)))
{
result = false;
}
}if (result)
{
int guessInputInt = Integer.parseInt(guessInput);
if (guessInputInt >= minGuess && guessInputInt < maxGuess)
guesses.add(guessInput);
else
result = false;
}else
System.out.println("Your input is not valid.");
return result;
}
Approach to break the loop is better amongst the two. Also, you can move the Sysout statement inside the loop e.g.:
private boolean isValid(String guessInput){
for (int i = 0; i < guessInput.length() && result; i++){
if (!Character.isDigit(guessInput.charAt(i))){
return false;
}
}
return true;
Update
Here's another way to do it (using java 8 stream):
public static boolean isValid(String s){
return !s.chars()
.filter(c -> !Character.isDigit((char)c))
.findFirst()
.isPresent();
}
Agreed with Mark Jeronimus's point. You should call this method and print the messages in calling the method rather than having Sysout in the valildating method.
How about a third option:
private boolean isValid(String guessInput) {
boolean result = isNumeric(guessInput);
if (result)
// ...
}
private boolean isNumeric(String input) {
for (int i = 0; i < guessInput.length(); i++)
if (!Character.isDigit(guessInput.charAt(i)))
return false;
return !input.isEmpty();
}
Or even simpler:
private boolean isValid(String guessInput) {
try {
int guessInputInt = Integer.parseInt(guessInput);
if (guessInputInt >= minGuess && guessInputInt < maxGuess) {
guesses.add(guessInput);
return true;
}
} catch (NumberFormatException nfe) {
System.out.println("Your input is not valid.");
}
return false;
}
On a side note, the method name isValid() implies a read-only getter, which is very misleading when you're modifying state.
In your loops, if you can accurately specify your loop breaking condition in the for loop itself, that is always better.
I always think of break as a hack/patch/fix, never a solution.
Specifically to the question on the usage of break in the loop in your example, I don't think there is a difference in code readability, since it is so short.
However, in general I would prefer the break approach, because:
There is no reason to continue execution once the result is set to false. Depending on the length of "guessInput", and how the compiler may optimize your code, the code with break can be a lot more efficient.
Although the code inside for loop is short in your example, in practice it may likely to grow as the condition become more complex. By always breaking out of the loop where it should, it will become a lot easier follow the code logic when the code inside loop becomes longer or more complex.
Therefore, I would always prefer to use break where it should in a loop.
For this I like the use of
public boolean isValid(String s) {
if (isNum(s)) {
Integer num = Integer.parseInt(s);
return inRange(num, maxGuess, minGuess);
}
return false;
}
private boolean inRange(Integer i, Integer max, Integer min) {
return (i < max && i >= min);
}
private boolean isNum(String s) {
return s.chars().allMatch(Character::isDigit);
}
As others have mentioned System.out.println("Your input is not valid."); is best done by the consumer of the isValid function,
Breaking isValid into smaller operations helps with MURDER!
You can read about murder here
If your intention is to validate numbers, any numbers, then you'd use the API for that, and handle the exception if the number is invalid.
Caveat: In your code, if your string is over 2147483647, the exception is thrown anyway and unhandled, leading to bugs.
Here's a better version, although I'd still argue about splitting up responsibilities in a pure checking method and another method that adds it to the guesses and/or prints stuff.
private boolean isValid(String guessInput)
{
try {
int guessInputInt = Integer.parseInt(guessInput);
if (guessInputInt >= minGuess && guessInputInt < maxGuess) {
guesses.add(guessInput);
} catch (NumberFormatException ex) {
System.out.println("Your input is not valid.");
return false;
}
return true;
}

Recursion to check if a String equals another string

my current code returns the output:
true
Expected: true
false
Expected: true
false
Expected: true
false
Expected: false
false
Expected: false
So there's an issue with my logic that i'm not seeing
public static void main(String[] args)
{
System.out.println(find("",""));
System.out.println("Expected: true\n");
System.out.println(find("Mitten","Mit"));
System.out.println("Expected: true\n");
System.out.println(find("I love my CS courses!"," CS"));
System.out.println("Expected: true\n");
System.out.println(find("","Cookies."));
System.out.println("Expected: false\n");
System.out.println(find("Java","Python"));
System.out.println("Expected: false\n");
}
public static boolean find(String text, String str)
{
boolean found = false;
if(text.length() == 0 && str.length() == 0)
{
found = true;
return found;
}
if(text.length() == 0 || str.length() == 0)
{
return found;
}
if(str.length() > text.length())
{
return found;
}
if(str.equals(text.substring(0,str.length()-1)))
{
found = true;
}
else
{
text = text.substring(1);
find(text, str);
}
return found;
}
please help
I see an issue with this statement
if(str.equals(text.substring(0,str.length()-1)))
Since the second index of substring is exclusive, it should be
if(str.equals(text.substring(0,str.length())))
in order to compare str to the first str.length characters of text.
Of course you can use text.contains(str) or text.startsWith(str) and eliminate some of your code, but perhaps that's not part of the exercise requirements.
Beside that issue, when you make a recursive call, you should usually do something with the value returned by that call :
found = find(text, str);
otherwise, why make the recursive call in the first place? (unless it has side effects of mutating the objects passed as parameters to the recursive call, which it does not in your case)

CodingBat xyzThere

Return true if the given string contains an appearance of "xyz" where the xyz is not directly preceeded by a period (.). So "xxyz" counts but "x.xyz" does not.
I am trying this problem out and cant seem to find why "abc.xyzxyz" is still returning false
public boolean xyzThere(String str) {
if(str.contains("xyz")) {
int xyz = str.indexOf("xyz");
if(xyz!=0 && str.substring(xyz-1,xyz).equals(".")) {
return false;
}
return true;
}
return false;
}
It returns false because this statement, if(xyz!=0 && str.substring(xyz-1,xyz).equals(".")) { is true.
xyz is 4, and str.substring(3, 4) is "."

Categories