Primitive-recursive even/odd - what does it do exactly? - java

I know that this method checks if the integer is even, but how exactly? I understood on examples like fibonacci or factorial how recursion works but not on this on. I think I don't get it because of the syntax.
// Assume n >= 0
public static boolean even(int n) {
return (n<=1) ? (n==0) : !even(n-1);
}
What my problem is: It's a boolean method, why is there no "true" or "false"?
How exactly does it check if it's even? If I would do it in if-statements without recursion I would check it like this:
if((n%2) == 0)
return true;

it's a JAVA short if else:
condition ? trueCase: elseCase;
it equals to below syntax:
if(condition){
trueCase;
}
else{
elseCase;
}
In your code:
return (n<=1) ? (n==0) : !even(n-1);
equals to:
if(n<=1)){
if(n==0){
return true;
}
else{
return false;
}
}
else{
if(even(n-1)){
return false;
}
else{
return true;
}
}

The statements
if((n%2) == 0)
return true;
else
return false;
is equivalent to
return (n%2) == 0;
any expression that evaluates to a boolean value can be used instead of directly using one of the two boolean values.
As for the function named "even", it basically says an integer is even if the previous integer is not even, unless it is smaller than one, in which case it is even if it is zero. Since it evaluates to a boolean value, so you can return it as the return value.
You should note that your function does not work for negative values.

Related

returning a boolean value from a recursive method

this is a supplementary question aligned to a question I asked recently. I have the following recursive code that will give me the largest number from a List of integers
static int maximum (List<Integer> a)
{
if ((a.getTail().isEmpty()))
return 0;
else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
return (a.getHead());
} else {
return m;
}}
}
This is helpful. But what I really want to do is to be able to return a Boolean value true or false depending on where the list increases in value or decreases. So my method would become:
static boolean maximum (List<Integer> a)
{
if ((a.getTail().isEmpty()))
return true;
else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
return true;
} else {
return false;
}}
}
But this will not run. The challenge I am faced with is that the recursive call as I have written returns an integer so that I can compare the previous maximum with the current maximum ----- if (a.getHead() > m).
What I want to do is to try and complete the assessment of the current verses previous max within the recursive call so that I only have to return a Boolean, true or false.
So for example if as the recursion occurs the list continually increases then the Boolean stays true but if at any point it decreases then it will give a false:
1,2,3,4 = true
1,2,4,3 = false
Thank you for your help I am really struggling with the whole concept of recursion.....
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(i==0) { return true; }
else { return false; }
can be shortened to return count==0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
what you want, is something like this:
static boolean is_sorted(List<Integer> list)
{
return is_sorted_from(0, list);
}
static boolean is_sorted_from(int index, List<Integer> list)
{
if(index+1 >= a.size()) { return true };
return list.get(index) < list.get(index+1)
&& is_next_sorted(index+1, list);
}
static boolean maximum (List<Integer> a, boolean cont){
if(cont){
if ((a.getTail().isEmpty())){
cont = false;
}else {
int n = maximum(a.getTail());
System.out.println(n);
if (a.getHead() > n) {
maximum(a.getHead(), cont);
} else {
maximum(n, cont);
}
}
}
return cont;
}
I'd say to make the method void or return the List, but I left it as boolean since that is technically what your question asked for.
You would just call the method with cont having the value of true. By using two parameters, you can continue comparing your max function while simultaneously using a boolean as your recursion flag. You would not be able to return your maximum however, but you could work around this by setting the maximum to either a class instance or to an object that you have as your third parameter (Double, Integer, etc.).

writing a java method that returns a boolean from a search

I have written a method that searches a tree to test if any integers are negative.
But I am struggling to get the right Boolean value returned. Any pointers as to where I am going wrong?
What I want to achieve is that as soon as the condition statement is met a false is returned but unfortunately my code is always returning a true
static boolean allE(Tree<Integer> x) {
if (x.isEmpty()) return true;
else {
if (x.getValue()%2 != 0) return false;
}
allE(x.getLeft());
allE(x.getRight());
return true;
}
When you recurse on allE you need to consider the result of that recursion. Easiest fix I see, change
allE(x.getLeft());
allE(x.getRight());
return true;
to
return allE(x.getLeft()) && allE(x.getRight());
Although, I think it makes more sense to write the algorithm such that you recurse on even explicitly. And allE saves three letters compared to allEven (please use meaningful names for methods and variables). Something like,
static boolean allEven(Tree<Integer> node) {
if (node.isEmpty()) {
return true;
} else if (node.getValue() % 2 == 0) {
return allEven(node.getLeft()) && allEven(node.getRight());
}
return false;
}
You're not using the results of your recursive tests properly.
It should be:
if (x.isEmpty()) {
return true;
}
boolean thisNodeEven = x.getValue() % 2 == 0;
return thisNodeEven && allE(x.getLeft()) && allE(x.getRight());
I suppose you need to evaluate the return-value of the recursive calls:
static boolean allE(Tree<Integer> x)
{
if (x.isEmpty())
return true;
else {
if (x.getValue()%2 != 0) return false;
}
if(!allE(x.getLeft()) || !allE(x.getRight()))
return false;
return true;
}

Trying to compile code but keep getting the same error?

I keep getting the error: "missing return statement." Isn't my return statement listed 5 times? Does anyone know why I'm getting this and how to fix it? It refers to the second to last bracket. Any help/ideas as to why this is happening is appreciated. Thanks.
public class words
{
// instance variables - replace the example below with your own
private String w;
/**
* Default Constructor for objects of class words
*/
public words()
{
// initialise instance variables
w="";
}
/**
* Assignment constructor
*/
public words(String assignment)
{
w=assignment;
}
/**
* Copy constructor
*/
public words(words two)
{
w=two.w;
}
/**
* Pre: 0<=i<length( )
* returns true if the character at location i is a vowel (‘a’, ‘e’, ‘i', ‘o’, ‘u’ only), false if not
*/
private boolean isVowel(int i)
{
if (w.charAt(i)=='a')
return true;
else if (w.charAt(i)=='e')
return true;
else if (w.charAt(i)=='i')
return true;
else if (w.charAt(i)=='o')
return true;
else if (w.charAt(i)=='u')
return true;
}
}
Tell me what do you return if w.charAt(i) is 'b'.
You need to add a last line:
private boolean isVowel(int i)
{
if (w.charAt(i)=='a')
return true;
else if (w.charAt(i)=='e')
return true;
else if (w.charAt(i)=='i')
return true;
else if (w.charAt(i)=='o')
return true;
else if (w.charAt(i)=='u')
return true;
else return false;
}
private boolean isVowel(int i){
//...
return false;
}
You are missing the case when your i is not a vowel.
Problems
Use brackets. Code without them is annoying to read.
Use the && operator when checking multiple if statements with the same body (all return true)
Use a switch statement if you are comparing the same thing (w.charAt(i)) multiple times but they have different bodies
The actual problem you have here is that if w.charAt(i) is not a vowel then it returns nothing. Include a return statement after all your checks
Use a for loop with an array of vowels
(Note: I have intentionally not included code because it is not helpful to give you the answer. If you don't understand any of the terms used above, comment or google them to understand completely. That will allow you to get the most out of the answer.)
private boolean isVowel(int i)
{
if (w.charAt(i)=='a')
return true;
else if (w.charAt(i)=='e')
return true;
else if (w.charAt(i)=='i')
return true;
else if (w.charAt(i)=='o')
return true;
else if (w.charAt(i)=='u')
return true;
return false;//Default return statement if nothing has matched.
}
--You are missing default return statement. If no match found what your metohd will return ?
--It was the issue, i have updated your code here, if nothing found it will return false.
While other people are explaining the code does not compile because of a missing return statement, I would like to point out you can basically do this as an one liner as shown below.
private boolean isVowel(int i) {
return w.charAt(i) == 'a' || w.charAt(i) == e || w.charAt(i) == 'i' || w.charAt(i) == 'o' || w.charAt(i) == 'u';
}
You are missing the return in your code. Ideally you should not have that many returns.
private boolean isVowel(int i)
{
boolean found=false;
if (w.charAt(i)=='a')
found= true;
else if (w.charAt(i)=='e')
found= true;
else if (w.charAt(i)=='i')
found= true;
else if (w.charAt(i)=='o')
found= true;
else if (w.charAt(i)=='u')
found= true;
return found;
}
You have two options
1. to use a flag like above. you should use brackets, that makes the code easy to read.
2. at the end of your code, just add return false.

Second return statement nested in if statement

I am wondering what return str.substring(1,4).equals("bad"); is doing here in the else if(len>=4). I think the if statement is a guard clause but I am not 100%. Can I have an explanation of what exactly is going on here? How is this read to output "false"?
Given a string, return true if "bad" appears starting at index 0 or 1 in the string, such as with "badxxx" or "xbadxx" but not "xxbadxx". The string may be any length, including 0. Note: use .equals() to compare 2 strings.
hasBad("badxx") → true
hasBad("xbadxx") → true
hasBad("xxbadxx") → false
public boolean hasBad(String str)
{
int len = str.length();
if(len == 3 && str.equals("bad"))
return true;
else if(len >= 4)
{
if(str.substring(0, 3).equals("bad"))
return true;
return str.substring(1, 4).equals("bad");
}
else
return false;
}
if(str.substring(0, 3).equals("bad")) is the easy part. "Return true if 'bad' is the beginning of the String.'
return str.substring(1, 4).equals("bad") essentially means, "Return true if 'bad' occurs after the first character, and false otherwise". This is basically a shortcut of
if(str.substring(1, 4).equals("bad")) return true;
else return false;
Because the if already evaluates a boolean (what goes inside of an if results in a boolean value), there's no reason to tell it to return "true if true, else false", you can just return the boolean value directly.
you can try it in other way too, like below one
public static boolean hasBad(String str) {
for (int i = 0; i < str.length() - 1; i++) {
if (str.length()>=3 && str.charAt(0) == 'b' || str.charAt(1) == 'b' ) {
if (str.substring(i).contains("bad")) {
return true;
}
}
}
return false;
}

this method must return a result of type boolean

i am rewriting class string in java but for some method like startwith i have the same error. this is my code:
public boolean mystartwith(MyString s){
if(s.mylength() > this.mylength()){
return false;
}else{
for(int i=0 ; i<s.mylength() ; i++){
if(lesCaracteres[i] != s.lesCaracteres[i]){
return false;
}else{
return true;
}
}
}
}
and i have this error : "this method must return a result of type boolean"
If s is empty, for loop will be skipped - and your method won't return anything at all, hence the error. I'd rather add checking for this condition first.
Have to note, though, that given algorithm is flawed:
for (int i=0; i<s.mylength() ; i++){
if (lesCaracteres[i] != s.lesCaracteres[i]){
return false;
} else {
return true;
}
}
Ok, let's say I called this function with 'abc' string given as s, but instance wraps over the string 'acdef'. Guess what, your method will return true! The problem is that your loop breaks too soon: a value is returned right after checking for the first letter.
Actually, it should be written like this:
int sLength = s.myLength();
if (sLength == 0) {
return false;
// actually, it's for you to decide:
// technically each string begins with an empty string
}
if (sLength > this.mylength()) {
return false;
}
for (int i = 0; i < sLength; i++) {
if (lesCaracteres[i] != s.lesCaracteres[i]){
return false;
}
}
return true;
The key difference: true is returned only if for loop is walked over normally (i.e., exited via i < sLength condition. That, in turn, means, that all the characters of s string match those at the beginning of the string wrapped.
if(s.mylength() > this.mylength()){
return false;
}else{
for(int i=0 ; i<s.mylength() ; i++){
if(lesCaracteres[i] != s.lesCaracteres[i]){
return false;
}else{
return true;
}
}
return ____; //place true or false based on your condition
}
Suppose if(s.mylength() > this.mylength()) is not satisfied, then your code will go to the loop.
Now suppose the for loop doesn't loop, meaning s is empty. What will be returned?
Exactly! Nothing, since the loop will be skipped.
To fix this, you should return some boolean after the loop.
Java must guarantee that a boolean will be returned whatever the input, however there are conditions in which there is no return
public boolean mystartwith(MyString s){
if(s.mylength() > this.mylength()){
return false;
}else{
for(int i=0 ; i<s.mylength() ; i++){
if(lesCaracteres[i] != s.lesCaracteres[i]){
return false;
}else{
return true;
}
}
//what if s.mylength()==0 and the loop never runs?!
//therefore the code will get to here, and the method will end without a return
}
}
Note that java isn't "clever enough" to recognise that two ifs together make all posibilities. For example
boolean method(int a){
if (a>0){
return true;
}else{
if (a<=0){
return false;
}
//program can never get here, BUT java doesn't realise that
}
Still doesn't satisfy java because it imagines a scenario where both ifs are false
How to fix this depends on your specific program, but it's worth noting that the for loop will only run once at most before returning so is superfluos
You can to redefine your code like this:
public boolean mystartwith(MyString s){
if(s.mylength() > this.mylength()){
return false;
}else{
for(int i=0 ; i<s.mylength() ; i++){
if(lesCaracteres[i] != s.lesCaracteres[i]){
return false;
}else{
return true;
}
}
return false;
}
}

Categories