This is the line I have trouble understanding
return (match(regex.substring(1), s)|| match(regex, s.substring(1)));
My understanding is that it would call the latter if the first method is false. So I wrote an simple program to test.
public static void main(String[] args)
{
System.out.println(test(5));
}
public static boolean test(int a)
{
System.out.println(a);
if (a>10)
return true;
if (a==4)
return false;
else
return (test(a-1) || (test(a+1)));
}
But it just prints 5 4 6 5 4 6...
A logical OR is true if either the left or the right expression is true. If the left expression is true, a computer language can opt not to evaluate the right expression to save time. That is, in fact, exactly what Java does.
That means that
match(regex, s.substring(1))
will be executed if and only if
match(regex.substring(1), s)
is false.
So the return value is:
true if match(regex.substring(1), s) returns true,
the return value of match(regex, s.substring(1) otherwise
It's equivalent to:
if match(regex.substring(1), s) return true;
if match(regex, s.substring(1)) return true;
return false;
The program you wrote calls test with a 5 as a param. This prints the five. This is not bigger than 10 of 4, so it goes to the else. In the else you call it's own method recursively, with a 4 the first time. So the 4 is printed This returns a false. Then it tries the second which is a+1, so it calls test with a 6. This prints the 6 on the screen, falls through to the else, and calls test again recursively, with a (which is now 6) -1 so with a 5. This loop is endless.
You have to put the first if:
if (a==4)
This fixes the program, but not what you want to get.
Also the problem is that you use the logical or completely wrong. An OR is meant to see if one of the both answers is true. If you want to call a method depending on a situation, you have to use an if or a ternary operator.
public static void main(String[] args)
{
System.out.println(test(5));
}
public static boolean test(int a)
{
System.out.println(a);
if (a>10)
return true;
if (a==4)
return false;
else
if(test(a-1)) {
return test(a-1);
}
else {
return (test(a+1));
}
}
This should give you what you want I guess
Related
The compiler keeps telling to return string.I used if-else condition and from within if-else i have returned string.The compiler problem will be solved if i put return statement at the end of the code but my problem will start .I dont understand how to solve this problem.I want to return right when its right.
Code:
public String isValidID(String id) {
if(getId().length()!=6) {//checks for 6 digit id
return "wrong";
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return "wrong";
}
}
}
In reply to my comment to add return "right" at the end, you said:
but that will make the program return "right " always.Becoz after if-else condition check ,the compiler will execute rest statement and will return "right" always
Now the source of your confusion is clear: return doesn't just set the value the method will return, it also exits the method, immediately. So for instance, the return "wrong"; inside your loop will exit from the loop, and the method, immediately. This is true of all the languages I've seen that use the return keyword (whereas there are some languages, like VB/VB.Net, where you assign a value to the function's name to set the return value, but execution continues normally until you use "exit").
That's why adding return "right"; at the end is how you resolve this, because the code won't reach that point if it ever reached return "wrong"; during the program flow above it:
public String isValidID(String id) {
if(getId().length()!=6) {//checks for 6 digit id
return "wrong"; // <== Exits immediately if reached
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
return "wrong"; // <== Exits immediately if reached
}
}
return "right"; // <== Exits immediately if reached
// (granted, we would have exited
// below anyway :-) )
}
In any condition, you need to return "something". In your code it possible that return never executed in a certain condition. Suppose your program execution comes to if(Id.charAt(i)>'9'||Id.charAt(i)<'0') and it never gets true then what the method will return? So, You need to write the code in a manner that in condition method execution will execute a return statement which returns a String object.
Just imagine a conditon Suppose
1. getId().length()!=6 -> false
2. getId().length() is 0
3. for(int i=0;i<getId().length();i++) will never enter the loop.
Then what should the method returns when you call it.
If I can understand your logic you can just use :
public String isValidID(String id) {
return id.matches("\\d{6}") ? "correct" : "wrong";
}
You check the length if it is 6 or not then you check if all characters are digits, you can combine both of them in one instruction, just check if the input is a number with length 6 with regex.
If you want a clean solution use boolean instead of a String in this case you can use :
public boolean isValidID(String id) {
return id.matches("\\d{6}");
}
Inside your else you have another if statement, so your return its not always reached. You need another return after the for cycle.
And you are checking if something is wright or wrong you should return Boolean true or false.
public boolean isValidID(String id) { if(getId().length()!=6) {//checks for 6 digit id return false; }
else{//checks if digit contains invalid entry for(int i=0;i'9'||Id.charAt(i)<'0') return false; }
return true;// when nothing false was found.
}
}
So in your case, I would have done public boolean isValidID instead.
Here, the compiler tells you to return something in case the length of the ID is not correct and the components of the ID (so the caracters) are between 0 and 9 (for example if your ID is something like 00ggg89, then I suppose it is wrong, but if your ID is 000000, then it could be right. Here is what I would have done
public boolean isValidID(String id) {
return id.matches("[0-9]{6}");
}
Hope this helps ! :D
public String isValidID(String id) {
String result = "right";
if(getId().length()!=6) {//checks for 6 digit id
result = "wrong";
}
else{//checks if digit contains invalid entry
for(int i=0;i<getId().length();i++){
if(Id.charAt(i)>'9'||Id.charAt(i)<'0')
result = "wrong";
}
}
return result;
}
Edit: In case the first statement is not valid it will never get to a return statement. Thats why you have to return a String in every possible case.
Currently on the chapter in my book where we talk about for loops and loops. I have sometimes come across an issue where the method needs me to return something. For example consider my code
below. Basically the exercise is to get all the factors in ascending order. Now heres the issue
As you can see I need a return statement outside of the for loop. Now I guess my book didn't exactly explain this properly, or I didn't understand the concept
of return properly in java, but does our return statement always have to be in the most outer indentation if you will?
The thing is, I don't really want to return anything outside of the for loop. I just want to return i upon that condition. Why doesn't java let me do this?
Whats a good counter-action?
Ever since I started learning loops and for loops, I have been having trouble understanding this. I guess I could just system.out.println(i) instead of returning it? But then what should I return? I could also make it a void type, and then make another method to print it, I guess?
class factors{
private int num;
public factors(int num)
{
this.num = num;
}
public int getFactors()
{
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
return i;
}
}
// I NEED TO PUT A RETURN STATEMENT HERE
}
}
public class test{
public static void main(String [] args)
{
factors fact = new factors(20);
System.out.println(fact.getFactors());
}
}
IT WORKS NOW ( I dont particularly like my solution)
class factors{
private int num;
public factors(int num)
{
this.num = num;
}
public void getFactors()
{
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
System.out.println(i);
}
}
}
}
public class test{
public static void main(String [] args)
{
factors fact = new factors(20);
fact.getFactors();
}
}
The thing is, I don't really want to return anything outside of the for loop. I just want to return i upon that condition. Why doesn't java let me do this?
Java lets you do that. There is nothing wrong with returning inside the loop upon reaching the condition.
Java allows you to have multiple return statements, so adding another return 0; after the loop is allowed.
Java returns once it hits the first return statement, and other return statements are not executed (the method isn't executed anymore) (except for some rare edge cases with try-catch and return, but thats another story entirely).
But why is it required?
Java requires that for all possible paths there exists a return with the proper type. Even if you yourself can proof mathematically that the path Java complains about is never taken, the compiler might not be able to prove that the path is not possible at runtime. So you simply need to add an return there with a dummy value.
In your concrete example, there is a condition in which the loop gets never executed. If num <= 0, then the loop condition is never satified and the entire loop body is skipped. Without the return,the method is invalid, because you can't return nothing from an method with return type int.
So, in your example, the compiler is actually smarter then you, and prevents you from making a mistake - because it found the path you thought wouldn't occur.
new factors(-1).getFactors(); // you don't check the passed value at all ;)
From your comments, it seems that you want to return all factors. In java, you return once, and only once, from a function. This means you have to aggregate the results and return a List or array of values:
public List<Integer> getFactors(int num) {
List<Integer> factors = new ArrayList<>();
for (int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
factors.add(i);
}
}
return factors;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(new factors(20).getFactors());
// prints a comma-separated list of all factors
}
does our return statement always have to be in the most outer indentation if you will?
No.
However, all potential code paths must return something. Consider this structure:
for(int i = 1 ; i<num ; i++)
{
if (num % i == 0)
{
return i;
}
}
What happens if num is a value where the loop itself is never entered? Or what happens if the if condition is never satisfied? No return statement would ever be encountered, which is invalid.
The compiler has to guarantee that the method will return something, under any and all potential runtime conditions. So while it's perfectly valid to return from within the loop, you also must provide logic for what to return if that return statement is never reached.
Java doesn't let you do that because what happens if the if (num % i == 0) is never true?
The methods return type is int, so it has to return an int. And it's possible that the if statement could be false, not every condition is covered with a return statement.
So if you wanted to you could return something like -1, or another invalid value. Then you know that the function didn't find what it was looking for.
I am pretty new to Java what I am trying to do may seem really strange but it is a matter of me understanding a little bit about how Java works more than actually accomplishing a set result.
If I have a boolean method for instance:
public class doThings
{
// imagine the intial value of this variable is set
// and or modified using getters and setters between the declaration
// and the following method
private boolean boolVar;
public boolean doSomething()
{
if(boolVar == true)
{
//does things and then returns true
return true;
}
else
{
return false;
}
}
}
And I want to call this method in another class like so...
public class testDoThings
{
doThings someObject = new doThings;
public static void main(String[] args)
{
someObject.doSomething()
}
}
How do I check (in the class testDoThings) to see if the method has returned true or returned false and print messages accordingly something like this...
public class testDoThings
{
doThings someObject = new doThings;
public static void main(String[] args)
{
someObject.doSomething()
if (doSomething() returns true) // yes I am aware this is not
//valid
{
// print a statment
}
else if (doSomething() returns false) // yes once again not valid
{
// print a different statement
}
}
}
I am aware that you could put these messages in the class containing the method but if I want different messages depending on where the method is called and what it is a called on then putting things in the original class method is not always going to work.
If I am completely off the track here please let me know, if someone can explain this to me though, that would be great!
You can try like this:
if (someObject.doSomething()) //So if your function returns true then the below statement will be executed
{
// print a statment
}
else //This will check for the false condition of your function
{
// print a different statement
}
You can try something like this:
if(someObject.doSomething()){
System.out.print("foo1");
}
else{
System.out.print("foo2");
}
Here's one way:
if(someObject.doSomething() == true){
System.out.print("foo1");
}
else{
System.out.print("foo2");
}
Generally you compare two things using == operator: if (x == y) ... so we have:
if ( someObject.doSomething() == true ) {
//statements
} else {
//statement for the case where result of method call is false
}
BTW instead of if(x == true) you can simply write if(x).
Conditional structures like if, while, do..., etc receive a boolean value, so it isn't necessary to put "boolVar == true". Just doing "if (boolVar)" is enough. As for your example in the doSomething method, just doing "return boolVar;" would do the work, without the need of any ifs, unless you pretend to do some more things on it.
To check a function return value works in the same way. I mean, variables have a value and functions also, the only difference is that variables hold a value while functions calculate or generate a value. So, in your code:
public class testDoThings {
public void check() {
doThings someObject = new doThings();
boolean flag = sameObject.doSomething();
if (flag) {
// print a statment
} else {
//If you want to check falsehood, !flag would do.
// Notice the "!" sign before
// the flag variable?
// It is a NOT sign, so
// NOT true = false
// NOT false = true
// The if will execute its code
// When the result value is true
// So when the function return val is
// false.
// print a different statement
}
}
}
I hope this explanation is enough clear.
is it possible by any means in the following method that the print statement get executed after the if statement returns true in the for loop?
public boolean contains(Object o) {
if(o == null){
throw new IllegalArgumentException();
}
for(int i = 0; i < size(); i++){
if(o.equals(getNodeAt(i).data)){
System.out.println("contains passed here: "+o+" "+getNodeAt(i)+" "+i);
return true;
}
System.out.println(getNodeAt(1));
}
System.out.println("cointain failed here "+o);
return false;
}
Of course; call the method again. More effectively, efficiently, and specifically with an Object such that o.equals(getNodeAt(i).data is false. The truth is...
"[B]y any means" is a pretty loose constraint; you say...
is it possible by any means in the following method that the print statement get[s] executed after the if statement returns true in the for loop?
I'm saying that YES, that's possible by any means when the means are recalling the method. In fact, it's perpetually true as long as you're using whatever container.
Proof:
Assume that it is impossible by any means in the following method that the second return statement gets executed after the if statement returns true in the for loop.
static String proof(Object o) {
for(int i = 0; i < 1; ++i) {
if (o == null) {
return "I'm returning from the for loop!!!";
}
}
return "I'm now called after the for's return statement (by any means)!! - QED";
}
But given...
public static void main(String...args) {
System.out.println(proof(null));
System.out.println(proof(new String("Hello Proof!")));
}// end main method
the ouput is...
I'm returning from the for loop!!!
I'm now called after the for's return statement!! - QED
Therefore our assumption is wrong and it is possible by some means for the second return statement to get executed after the if statement returns true in the for loop.
;)
A "better" way to phrase that so it's clear what you're asking would be, perhaps, - "Is it possible for the code in a method body to continue to execute after a return statement?"
That answer is no and can be tested in any good IDE as follows.
static String proof(Object o) {
for(;;)
if(true)
return "Donkey Butts";
return "Poops";
}
This basically says forever it is true that I will return "Donkey Butts". In any IDE I'd waste my time using you will get an error for "unreachable statement". The IDE can determine this truth from your code which implicitly is telling you that any time the loop is active and the if is true the code below cannot execute.
No, it is definitely not possible.
No, but it is possible that System.out isn't flushed until after the return statement.
Yes, if you enclose in a try and finally.
public boolean contains(Object o) {
if(o == null){
throw new IllegalArgumentException();
}
for(int i = 0; i < size(); i++){
try {
if(o.equals(getNodeAt(i).data)){
System.out.println("contains passed here: "+o+" "+getNodeAt(i)+" "+i);
return true;
}
} finally {
System.out.println(getNodeAt(1));
}
}
System.out.println("cointain failed here "+o);
return false;
}
Nothing inside a method can be executed after the return statement.
But when you deal with output operations, things can happen quite differently from what you might expect. In fact, writes to an output file/device are often buffered, i.e. written to an internal array. When the array is full, it is sent to the file/device. This happens for efficiency reasons, because writing a few big chunks of data is faster than writing lots of small ones.
This means that these operations sometimes seem to happen long after the place where they appear in the code.
so I'm a newish Java programmer, and this might just be a concept that went right over my head. but if I am calling a boolean method in a program, such as keepDice2 below, how can I check the return value-true of false- in an if statement? Below is my attempt.
I am attempting to make a method, keepDice2, return the boolean false if the user inputs a String containing 'N' or 'n'. Then, I want to make an if stateent: if the return value is the boolean false, then call the method rollDice2 ( I have not included rollDice2 as it seems irrelevant). ANy insight into this wwould be greatly appreciated!
public static boolean keepDice2() {
Scanner input = new Scanner(System.in);
System.out.println("Keep Dice Two?");
String keepDice = input.nextLine();
boolean answer;
if (keepDice.contains("n") || keepDice.contains("N")) {
answer = false;
//here, if the answer contains n or N, then it is a form of "No", so that dice will be re-rolled.
}
else {
answer = true;
}
return answer;
}
public static void (String[] args) {
if (keepDice2() == false) {
rollDice2();
}
}
keepDice2() returns boolean so you don't need to compare it. You also forgot to name the method which is main
public static void main (String[] args) {
if (!keepDice2()) {
rollDice2();
}
}
What have you written is correct, but you can achieve the same result with less code.
Everything inside one if statement brackets is a boolean expression. So if you want to write code that will run in case this expression returns true you just write this expression in bracket and that's it, if you want it to run in case it returns fals you just put ! in front of it.
Eq:
if(keepDice2()) {
rollDice2();
///////////////////////////////////////////
// put here rest of code you want to run //
// if keepDice2() returns true //
///////////////////////////////////////////
}
/*if keepDice2 returns false.
* But since
* there are only two possible outcomes
* you can just use else statement instead
* if else if with boolean expression in
* brackets
*/
else if (!keepDice2()) {
///////////////////////////////////////////
// put here the code you want to run //
// if keepDice2() returns false //
///////////////////////////////////////////
}