I have to implement Binary search method which finds if value is or isn't in array. I have to use recurse.
public static boolean searchBin(int[] array, int x, int l, int r) {
int center;
center =(l+r) / 2;
if ( x > array[center] )
{
l = center+1;
}
else
{
r = center-1;
}
if ( array[center] == x )
{
return true;
}
else
{
if ( l<=r )
{
searchBin(array,x,l,r);
}
else
{
return false;
}
}
}
I'm getting the following error:
Missing return statement
Thanks.
This is because as the error suggests "not all paths return a value".
This is the possible problem:
searchBin(array,x,l,r);
A fix will be:
return searchBin(array,x,l,r);
This is because one of the possible path of execution could lead to none of your return statements: in the last if, if the condition l<=r is true, nothing is returned (you only call recursively your method).
You might want to add the return keyword before your recursive call:
return searchBin(array,x,l,r);
This way, your method will (in this case) return whatever the recursive call returns.
There is no return where you have the recursive call to
searchBin
Related
I am working on a function, countH(), that is supposed to count the amount of times a given number appears in a linked list. For some reason, I cannot get this to work recursively. I have tried a number of different solutions but I guess I can't get something in the correct place. Sorry if I am asking the question poorly, I struggle to understand recursion formatting sometimes.
Here is the function:
public int count(int i) {
return countH(first, i);
}
private int countH(Node front, int i) { // TODO
int cter = 0;
if (front.next==null) {
return 0;
}
if(front.item == i)
cter++;
return countH(front, cter);
}
This is a late version of my code, I'm sure it was a bit better before I messed with it a bunch to try to get it to work
Thanks!
Every recursive implementation consists of two parts:
base case - that represents a simple edge-case for which the outcome is known in advance. For this task, the base case is a situation the given Node is null. Think about it this way: if a head-node is not initialed it will be null and that is the simplest edge-case that your method must be able to handle. And return value for the base case is 0.
recursive case - a part of a solution where recursive calls a made and where the main logic resides. In the recursive case, you need to check the value of a current node. If it matches the target value, then the result returned by the method will be 1 + countH(cur.next, i), otherwise it will be a result of the subsequent recursive call countH(cur.next, i).
Base case is always placed at the beginning of the method, followed by a recursive case.
And when you are writing a recursive part, one of the most important things that you have to keep in mind is which parameters change from one recursive call to another, and which remains the same. In this case, changes only a Node, the target value i remains the same.
public int count(int i) {
return countH(first, i);
}
private int countH(Node cur, int i) { // `front` replaced by `cur`
if (cur == null) { // not cur.next == null (it'll fail with exception if the head-node is null)
return 0;
}
// int cter = 0; // this intermediate variable isn't needed, it could be incremted by 1 at most during the method execution
// if(cur.item == i)
// cter++;
// return countH(cur, cter); // this line contains a mistake - variable `i` has to be passed as a parameter and `cter` must be added to the result returned by a recursive call
return cur.item == i ? 1 + countH(cur.next, i) : countH(cur.next, i);
}
Suggestion
Follow the comments in the code. I've left your original lines in place so that will be easier to compare solutions. Also, always try to come up will reasonable self-explanatory names for variables (as well as methods, classes, etc). For that reason, I renamed the parameter front to cur (short for current), because it's meant to represent any node, not first or any other particular node.
Side note
This statement is called a ternary operator or inline if statement
cur.item == i ? 1 + countH(cur.next, i) : countH(cur.next, i);
And it's just a shorter syntax for the code below:
if (cur.item == i) {
return 1 + countH(cur.next, i);
} else {
return countH(cur.next, i);
}
You could use either of these constructs in your code. The difference is only in syntax, both will get executed in precisely the same way.
In a linked list, you should have one element and from that you get the value and the next element. So your item could look like (I am omitting getters, setters and exception handling):
class Item {
Object value;
Item next;
}
Then your counter for a specific value could look like
int count(Object valueToCount, Item list) {
int result = 0;
if (valueToCount.equals(list.value)) {
result++; // count this value
}
if (value.next != null) {
result += count(valueToCount, value.next) // add the count from remainder of the list
}
return result;
}
public int count(int i) {
return countH(first, i);
}
private int countH(Node front, int i) { // TODO
if(front==null) {
return 0;
}
if (front.item == i) {
return 1 + countH(front.next, i);
} else {
return countH(front.next, i);
}
}
I am doing a project for school that requires us to use arrays to put 'Spherocylinder' objects within the array.
A spherocylinder object consists of (String label, double edge, double height)
I am trying to create a method that takes a (String labelIn) parameter and find a spherocylinder object that matches the parameter given and return it
public Spherocylinder findSpherocylinder(String labelIn) {
for (int i = 0; i < spObjects; i++) {
if (sList[i].getLabel().equalsIgnoreCase(labelIn)) {
return sList[i];
}
else {
return null;
}
}
}
It gives me a missing return statement and don't know how I would go about moving the return to outside of the 'for' statement. The project states that if no object is found to match the parameter it must return 'null'
Remove the else from the for loop and put the return statement outside the loop.
public Spherocylinder findSpherocylinder(String labelIn) {
for (int i = 0; i < spObjects; i++) {
if (sList[i].getLabel().equalsIgnoreCase(labelIn)) {
return sList[i];
}
}
return null;
}
The reason for this is that there might be a case where the for loop may not run even once so the function cannot return anything in that case. Compiler detects this and hence gives an error. It is unlike python where by default function returns a None.
An alternative is to use reduction like this :
public Spherocylinder findSpherocylinder(String labelIn) {
return sList.stream()
.filter(spherocylinder -> spherocylinder.getLabel().equalsIgnoreCase(labelIn))
.reduce((a, b) -> {
throw new IllegalStateException("Multiple elements: " + a + ", " + b);
})
.get();
}
This obtains the sole matching element from the stream, throwing
NoSuchElementException in case the stream is empty, or
IllegalStateException in case the stream contains more than one matching element.
I'm learning Java at the moment and have a task where I should create a method that keeps asking the user for input until one of two keywords are entered. It should then, depending on that return an int.
public static int getCommand(){
String command = IOTools.readString("Enter Command!");
if (command.equals("exit")){
return 1;
} else if (command.equals("shift")){
return 0;
} else {
getCommand();
}
}
The problem I'm having is that eclipse tells me to either change the return type to void or add a return statement after the if block.
Is there something wrong with my recursive approach?
You are missing the return statement on your recursive call
public static int getCommand(){
String command = IOTools.readString("Enter Command!");
if (command.equals("exit")){
return 1;
} else if (command.equals("shift")){
return 0;
} else {
return getCommand(); // Added return here
}
}
you need to add a return type in last case
public static int getCommand(){
String command = IOTools.readString("Enter Command!");
if (command.equals("exit")){
return 1;
} else if (command.equals("shift")){
return 0;
} else {
return getCommand();
}
}
this function getCommand(); call is returning an int value but not in else case so if the control falls inside your else case then your recursive functions calls will be executed though there is no assurance that getCommand(); will return an int value due to else case so compiler detects that hence the error and according to this case where return type is not void , java says
Every execution path in a function must lead to a RETURN statement
Return statement is missing here
else {
getCommand();
}
All paths of your methode need to return something.
I ma trying to check if a given Binary Tree is a Binary Search Tree. I am using in order traversal to do so. The idea is while traversing the tree in in order fashion, at each node check if the node value is greater tha the value of the previous noe visited. If not then then it is not a BST.
The question I have is why he first two work and not the third one :
// This works - Implementation 1
--------------------------------
class PrevWrapper
{
int data = Integer.MIN_VALUE;
}
public boolean isBST()
{
return isBST(root, new PrevWrapper());
}
private boolean isBST(Node node, PrevWrapper previousElement)
{
if ( node == null )
{
return true;
}
if ( !isBST(node.left, previousElement) )
{
return false;
}
if ( previousElement.data > node.item )
{
return false;
}
previousElement.data = node.item;
return isBST(node.right, previousElement);
}
// This works - Implementation 2
--------------------------------
static int lastValue = Integer.MIN_VALUE;
static boolean isBST(Node root)
{
if ( root == null )
{
return true;
}
if ( ! isBST(root.left) )
{
return false;
}
if ( root.item < lastValue )
{
return false;
}
lastValue = root.item;
return isBST(root.right);
}
// This does not work - Implementation 3
--------------------------------
private boolean isBST(Node node, Integer previousElement)
{
if ( node == null )
{
return true;
}
if ( !isBST(node.left, previousElement) )
{
return false;
}
if ( previousElement > node.item )
{
return false;
}
previousElement = node.item;
return isBST(node.right, previousElement);
}
Please explain. Wh can't I pass an Integer on function call stake that will maintain state ? or is it something that I am doing wrong with the implementation.
Although Integer is a wrapper class for integer, it is immutable. So once set, any edits will only create new objects of the kind, just like for Strings. So although implementation 3 tries to change the value of previousElement in the following line and hopes it will pass through to other recursive calls, it doesn't happen because of the way the Integer class works.
previousElement = node.item;
However Implementation 1, where you create a wrapper for the integer, it will maintain state because the class is passed by reference in subsequent recursive calls.
In the latest implementation, this piece of code is not doing what you expect it to:
if ( previousElement > node.item )
{
return false;
}
previousElement here should have the value of the rightmost leaf node of the left subtree, but instead it has the value of the parent node.
If you pass an Integer as an argument to the next recursive call of isBST, it becomes a local variable of that method, and any assignment done to it will not be seen by the caller of the recursive method when it returns.
This behavior is caused by Java being a pass by value language. When you pass a reference type to a method, that method gets a local copy of that reference. It can only change the state of the instance referred by that reference via methods that change its state (assuming it's mutable). That's what you do in the version that has a PrevWrapper parameter.
This is my method to find if a particular node is there in a binary tree.Here's my method and it works fine.
public boolean find(BinaryNode p,int x){
if(p==null){
return false ;
}
else{
if(x==p.element){
return true;
}
else if(x<p.element){
return find(p.left,x);
}
else {
return find(p.right,x);
}
}
}
My question is if I don't insert return keyword inside else if(x<p.element){ and else { I get an error as missing return statement.
Say I have a binary tree consisting of elements 5,4,6,60,25,10 .
So if i am searching for 10 there's a time that
if(x==p.element){
return true;
is satisfied because of recursive calls.Then there's a return statement to be found.
If i am searching for an element that's not in tree eventually I would reach the statement
if(p==null){
return false ;
},there we find a return statement.
Therefore even I don't have the return in else if and else clauses somehow there's a way that I finally reach a return statement right?So what's wrong with not having return keyword in else if and else clauses.
Why do I have to have it there?
Why can't I do it as
`public boolean find(BinaryNode p,int x){
if(p==null){
return false ;
}
else{
if(x==p.element){
return true;
}
else if(x<p.element){
find(p.left,x);
}
else {
find(p.right,x);
}
}
}`
The closest to the way you want your if-else if-else clause to behave is using the ? conditional expression:
public boolean find(BinaryNode p,int x)
{
if(p==null) {
return false ;
}
else {
return (x==p.element)?true:(x<p.element?find(p.left,x):find(p.right,x));
}
}
Other option is to store the value to be returned in a local variable and only return it at the end of your method:
public boolean find(BinaryNode p,int x)
{
boolean returnValue = false;
if(p!=null)
{
if(x==p.element){
returnValue = true;
}
else if(x<p.element){
returnValue = find(p.left,x);
}
else {
returnValue = find(p.right,x);
}
}
return returnValue;
}
And my favorite way, using short-circuit evaluation of logical expressions:
public boolean find(BinaryNode p,int x)
{
if(p==null) return false;
return x==p.element || (x<p.element && find(p.left,x)) || find(p.right,x);
}
Since Java's || and && operators won't evaluate their right part expression when the left part already determines their result. If x==p.element is true, then true will be returned without evaluation the rest of the line. If not, then (x<p.element && find(p.left,x)) will be evaluated following the same rule.
Note how find(p.left,x) won't be evaluated when x<p.element is false.
You need return statement because the find-function in the else if - else statement will return to the caller after its done, but the first-call function still have to return a value to the caller
Therefore even I don't have the return in else if and else clauses somehow there's a way that I finally reach a return statement right?
No compiler doesn't know about it. Compiler doesn't know what will be value of x and p at run-time.
Compiler simply checks for all the possibilities of the return statement and there must be exit point of the method.
You need to provide the logic to move either in right direction or left direction of the binary tree.
The last two else-if are not responsible to actually return the result of the find method its used just to move in the right direction of the tree. Ultimately final result of the the find method will come out by first two if-else clause.