So I'm defining a recursive function that takes as an argument a value for x (like the arithmetic variable x, i.e. "x + 3 = 5") and returns the result of the arithmetic expression. The expression is taken from a Binary expression tree that looks like this:
You start at the root and keep working your way down till you hit the leaves, and once you do you come back up. The expression on the tree is then:
x * ( (x + 2) + cos(x-4) ).
My code for this function is as follows:
// Returns the value of the expression rooted at a given node
// when x has a certain value
double evaluate(double x) {
if (this.isLeaf()) {
//convert every instance of 'x' to the specified value
if (this.value.equals("x")) {
this.value = Double.toString(x);
}
//return the string-converted-to-double
return Double.parseDouble(this.value);
}
//if-else statements to work as the arithmetic operations from the tree. Checks the given node and performs the required operation
else {
if(this.value.equals("sin")) { return Math.sin(evaluate(Double.parseDouble(this.leftChild.value))); }
if(this.value.equals("cos")) { return Math.cos(evaluate(Double.parseDouble(this.leftChild.value))); }
if(this.value.equals("exp")) { return Math.pow(evaluate(Double.parseDouble(this.leftChild.value)), evaluate(Double.parseDouble(this.rightChild.value))); }
if(this.value.equals("*")) { return evaluate(Double.parseDouble(this.leftChild.value)) * evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("/")) { return evaluate(Double.parseDouble(this.leftChild.value)) / evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("+")) { return evaluate(Double.parseDouble(this.leftChild.value)) + evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("-")) { return evaluate(Double.parseDouble(this.leftChild.value)) - evaluate(Double.parseDouble(this.rightChild.value)); }
}
}
However the compiler is tossing an error telling me that my function must return a type double. Both the if and the else statements return a double- the if statement directly and the else statement through the sum of 2 doubles returned by the same function. What is the deal here? If I place a return statement outside of the if-else then the error resolves itself but to work with that would require me to keep a static or a global variable consistent through each recursion. I'd like to know what is wrong with my function as is, because it feels much more intuitive than a global variable and I think I'm missing a key concept about recursion here. Any help is appreciated- thank you!
Both the if and the else statements return a double
They actually don't. The if branch always does, but the else branch doesn't. What happens if this.value equals "Invalid", or something else which isn't in your list? Then it won't ever hit a return statement. Since it's required to always return, or throw an exception, this isn't allowed.
Even if you have your program structured in such a way that it logically always has to return a value, the compiler isn't going to be doing complex analysis on all the branches of your program to ensure that it always returns something. It just checks that each branch has a valid return.
So, for example, something like is invalid
if(x < 0) return -1;
if(x >= 0) return 1;
Because the compiler doesn't know that it always has to hit one of those two conditions (an issue which is further complicated by the fact that, depending on what x is, it might not always have to go down one of those branches).
Instead, your code should be structured like this:
if(x < 0) return -1;
else return 1;
So that every branch has a valid exit condition.
Related
public boolean replaceEventAt(String eventStr, int position){
boolean answer = false;
if((position > 0) && (position <= events.size())){
events.get(position - 1) = eventStr;
answer = true;
}
return answer;
}
Error on fifth line where Java complains that position is a value not a variable please help
An assignment operates between what is known as an lvalue and an rvalue.
lvalue stands for left-hand-side-value.
rvalue stands for right-hand-side-value.
The rvalue can be many things, like a variable, a constant, a function call expression, etc, but the left side must be assignable, so it cannot be a constant or a function call.
In your case, your rvalue is a function invocation; that won't work. The compiler error message is saying exactly that.
If we knew what you are trying to do we could perhaps explain more, but it is unclear from the code that you posted that it is that you want to accomplish. Perhaps events is some collection, and you want to set the element at position position - 1 to eventStr, in this case you would probably want events.set( position - 1, eventStr );
Left hand side must be a variable (ie we should be able to assign a value to it ). But in your case it is performing a get operation So it is throwing an Error
As you are trying to replace using index I assume events is object of List interface.
In this case below code should work as per your requirement.
public boolean replaceEventAt(String eventStr, int position){
boolean answer = false;
if((position > 0) && (position <= events.size())){
events.set(position - 1, eventStr);
answer = true;
}
return answer;
}
I am using BlueJ IDE to write java programs.
I have a method with String return type. I have put the return statements within if-else, such that if the boolean variable "flag" has true value, then one value is returned, while if the value is false, another value is returned.
Now, the problem is that BlueJ asks for another return statement even after this, as shown below.
If I give another return after if-else, it works.
Why is this happening? I had learnt that there can be no statements after the return statement. So, why is the compiler asking for another return statement?
If someone wants the code for cut-paste purposes, here it is. This code is meant to convert binary numbers to their decimal equivalents, including fractions, but no negative numbers.
public class Conversions{
protected String Binary_Decimal(String str){
int a = str.indexOf('.');
boolean flag = false;
if (a == -1){
str += ".0";
a = str.indexOf('.');
flag = true;
}
String bd = str.substring(0, a);
String ad = str.substring(a + 1);
a = 0;
double num = 0;
for (int i = bd.length() - 1; i >= 0; i--){
num += Math.pow(2, a) * Integer.parseInt(Character.toString(str.charAt(i)));
a++;
}
if (flag == true){
return Integer.toString((int) num);
}
else if (flag == true) {
a = -1;
for (int i = 0; i < ad.length(); i++){
num += Math.pow(2, a) * Integer.parseInt(Character.toString(str.charAt(i)));
a--;
}
return String.valueOf(num);
}
return String.valueOf(num); //<-- WHY DOESN'T IT RUN WITHOUT THIS EXTRA return?
}
}
Here, str is the string that is input by the user using a different method Input().
The issue is that you wrote an if - else as an if - else if. The compiler does not understand or care that the two conditions you have are mutually exclusive and therefore cover all cases. Given how you wrote the branches, you need an explicit else or a catchall return for the compiler to be assured that the function always returns a String.
This is one example of why it is a bad idea to explicitly spell out the else when you have a set of conditions. The more important reason being that your if will often contain something much more complex and you might not negate it properly.
Delete the second ELSE IF clause and put the block directly after the first return statement, and consider that flag is a boolean. As follows:
if (flag) return Integer.toString((int) num);
a=-1;
for(....){
....
}
return String.valueOf(num);
In this way, the compiler should not notify you that error.
So, why is the compiler asking for another return statement?
Because you are missing a default return statement.
What if none of the conditions you have satisfied ? There must be something return default right ? That is what the issue is. That is why it is getting compiled when you uncomment that line.
Or even , you have an else statement, your program will have at least one satisfied return and it gets compiled too. Try it.
I had learnt that there can be no statements after the return statement.
This statement comes with some conditions. You have the return statement inside the if condition. So if your expression is not true, there is no way that the return gets execute.
I know basic if statement structure, but this confuses me
public void setHandleName(String handle){
if(handle.length() < 10){
return;
}
handleName = handle;
}
It returns the value when the handle.length() is bigger than 10, isn't it supposed to be returning the value when handle.length() is less than 10?
Why does this if statement does the opposite?
if(false){ //do stuff; }
Where the if statement should be
if(true){ //do stuff; }
Sorry for the vague explanation, english is not my native language.
Any help will be appreciated!
Thanks!
It returns the value when the handle.length() is bigger than 10
No it doesn't. It never returns any value, the method is of type void. It does set the handleName instance field if the name is at least 10 characters long (and not set it if the name is less than 10 characters long).
, isn't it supposed to be returning the value when handle.length() is less than 10?
No, the if clearly says "If the length of handle is less than 10, return" and that's before it sets handleName. return leaves the function right away, bypassing any code that may follow.
Why does this if statement does the opposite?
if(false){ //do stuff; }
Because in that case, the logic is within the if block; in your first example, it's after an if block that returns early (bypassing the remainder of the function). That is, your first example is:
if (!condition) {
return;
}
doSomething();
but your second example is
if (condition) {
doSomething();
}
Here's an annotated version of your first example:
public void setHandleName(String handle){ // Accept a `handle` string parameter
if(handle.length() < 10){ // If the length of `handle` is less
// than 10, enter the block
return; // Leave this method immediately, without
// doing anything else
} // This is the end of the conditional bit
handleName = handle; // Set `handleName` to `handle`
}
So if we go into the if block, we'll return, and never reach the handleName = handle; line, so we never set it. If we don't go into the if block, we don't return early, so we do set it.
We can (and probably should) rewrite setHandleName to use the structure from your later examples:
public void setHandleName(String handle){ // Accept a `handle` string parameter
if(handle.length() >= 10){ // If `handle`'s length is 10 or higher
handleName = handle; // Set `handleName` to `handle`
} // This is the end of the conditional bit
}
It doesn't return anything (as the void return type indicates). It sets the value of handleName to handle, but only if handle.length() is greater or equal to 10. If handle.length() is less than 10 it will just return from the method without doing anything more.
There are a few things to note:
The return type on this method is void. This means that it doesn't have a value to return. You can absolutely use return in a void method, but that implies...
This method returns early based on a condition. Effectively, if the value doesn't satisfy a specific criteria, it silently ignores what was passed into it.
Does this make it clearer what the code is actually doing?
public void setHandleName(String handle){
if(handle.length() >= 10){
handleName = handle;
}
// otherwise handleName is not set, and the method exits
// nothing is returned because the method is 'void'
}
Please note that if(false){ //do stuff; } will never "do stuff"
Can anyone help me to understand this line? I tried to transform it with "if .. else" but it didn't work. Thanks in advance.
return (patient1.isEmergencyCase() == patient2.isEmergencyCase()) ? (Integer.valueOf(patient1.getId()).compareTo(patient2.getId())) : (patient1.isEmergencyCase() ? -1 : 1);
if (patient1.isEmergencyCase() == patient2.isEmergencyCase()) {
return Integer.valueOf(patient1.getId()).compareTo(patient2.getId());
} else if (patient1.isEmergencyCase() ) {
return -1;
} else {
return 1;
}
In other words, it's a sorting, probably to decide which patient comes first. You would typically find such a code in a compareTo method, which is typically used to sort lists, in this case to define who gets "served" in which order.
It returns -1 if partient1 is "lesser/earlier/etc", which happens if both of them are emergency cases and patient1's id is lower OR if only patient1 is an emergency case, otherwise it returns 1 (or 0, is both are emergency cases and their ids are equals).
You can have a look if the concept isn't yet clear: Comparable.
if (patient1.isEmergencyCase() == patient2.isEmergencyCase()) {
return Integer.valueOf(patient1.getId()).compareTo(patient2.getId());
} else {
if (patient1.isEmergencyCase())
return -1;
else
return 1;
}
This is what has been condensed into the nested ternary expression.
The first step in understanding is to convert the expression inside the else into a ternary, and then work your way outwards.
That is,
if (patient1.isEmergencyCase())
return -1;
else
return 1;
is equivalent to return patient1.isEmergencyCase() ? -1 : 1.
But this expression itself is under the else condition.
What the code is doing is that if both patients are emergency cases, or both are non-emergency cases, then prioritize the one whose id comes first (according to the compareTo method). If, however, one patient is an emergency case while the other is not, then prioritize the emergency patient ... quite a realistic situation.
It's just like this:
if(patient1.isEmergencyCase() == patient2.isEmergencyCase()){
return Integer.valueOf(patient1.getId()).compareTo(patient2.getId());
} else {
if(patient1.isEmergencyCase()){
return -1;
} else
return 1;
}
It's a short way to write the same thing. Put the condition to evaluate before the '?' character, the put the two condition true : false.
Simple!
You should use nested if-else for producing output from this line....here multiple ternary operators are used ...
ternary operator---- condition?true statement :false statement;
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
My job is to write a recursive version to this method. From what I understand Recursion is starting with a base call (if something then return) followed by an else which unwinds back to the original base. Like starting with a deck, adding on to the deck then removing cards from the deck until you are back to the original deck.
With that in mind here it is.
public static long fact(int n)
{
long result = 1;
while(n > 0)
{
result = result * n;
n = n - 1;
}
return result;
}
//my recursive version:
public static void recFact(int n)
{
if(n==0)
{
return n; // ir 0 it really doesn't matter right?
}
else
{
return recFact(n-1);
}
}
This is just an example test problem for an exam I have coming up, just want to make sure I have a handle on recursion. Did I do this right? If not what am I missing? please no answers in questions, just tell me what I did wrong and maybe some advice on better ways to understand it.
Thanks.
No, this recursive solution is not correct.
For every positive n, you're just return rectFact(n-1), which will recourse until you reach 0, at which point it will return. In other words, your function will always return 0. You're missing the part where you multiply the current n with rectFact(n-1). Additionally, note that 0! is 1, not 0:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
else
{
return n * recFact(n-1);
}
}
And finally, since the if clause returns, the else is somewhat redundant. This doesn't affect the method's correctness, of course, but IMHO the code looks cleaner without it:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
return n * recFact(n-1);
}
Your recursive version does no multiplication, and it will return zero for any input. So no, you didn't do it right.
But, the recursive version DOES recurse, so you have that going for you! To understand what's going wrong, walk through a very simple case.
Client calls recFact(3)
This will return to client recFact(2)
Which will return to above recFact(1)
Which will return to above recFact(0)
Which will return to above 0.
There are two major things going wrong:
Your base case is wrong (zero is too low)
You're not doing any multiplication
Good attitude about not wanting the solution handed to you! Hopefully these pointers wil help you figure it out.
EDIT: Apparently I misunderstood your grammar and you did want the solution.
Any recursive function needs three things:
The terminating condition: This tells the function when to stop calling itself. This is very important to avoid infinite recursion and avoid stack overflow exceptions.
The actual processing: You need to run the actual processing within each function. In your non recursive case, this was result = result * n. This is missing from your recursive version!
A collector/agggregator variable: You need some way to store the partial result of the recursive calls below you. So you need some way to return the result of recFact so that you can include it in processing higher up in the call chain. Note that you say return recFact(n - 1) but in the definition recFact returns void. That should probably be an int.
Based from your example you are missing the return type of your recFact which is int
Also recFact will always return 0 because you are not multiplying n each time to the recursion call of the method.
There are two ways to write recursive routines. One is the "standard" way that we all are taught. This is one entry point that must first check to see if the recursive chain is at an end (the escape clause). If so, it returns the "end of chain" value and ends the recursion. If not at the end, it performs whatever calculation it needs to get a partial value according to the level and then calls itself passing a value the next increment closer to the end of the chain.
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int val ){
if( val < 2 ){
return 1;
}
else{
return recFact( val - 1 ) * val; // recursive call
}
}
//Output: "Fact(15) = 2004310016"
In regular recursion, a partial answer is maintained at each level which is used to supplement the answer from the next level. In the code above, the partial answer is val. When first called, this value is 15. It takes this value and multiplies it by the answer from Fact(14) to supply the complete answer to Fact(15). Fact(14) got its answer by multiplying 14 by the answer it got from Fact(13) and so on.
There is another type of recursion called tail recursion. This differs in that partial answers are passed to the next level instead of maintained at each level. This sounds complicated but in actuality, make the recursion process much simpler. Another difference is that there are two routines, one is non recursive and sets up the recursive routine. This is to maintain the standard API to users who only want to see (and should only have to see)
answer = routine( parameter );
The non-recursive routines provides this. It is also a convenient place to put one-time code such as error checking. Notice in the standard routine above, if the user passed in -15 instead of 15, the routine could bomb out. That means that in production code, such a test must be made. But this test will be performed every time the routine is entered which means the test will be made needlessly for all but the very first time. Also, as this must return an integer value, it cannot handle an initial value greater than 19 as that will result in a value that will overflow the 32-bit integer container.
public static final int MaxFactorialSeq = 20;
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int value ){
if( value < 0 || value > MaxFactorialSeq ){
throw new IllegalArgumentException(
"Factorial sequence value " + value + " is out of range." );
}
return recFact( value, 1 ); // initial invocation
}
private int recFact( int val, int acc ){
if( val < 2 ){
return acc;
}
else{
return recFact( val - 1, acc * val ); // recursive call
}
}
//Output: "Fact(15) = 2004310016"
Notice the public entry point contains range checking code. This is executed only once and the recursive routine does not have to make this check. It then calls the recursive version with an initial "seed" of 1.
The recursive routine, as before, checks to see if it is at the end of the chain. If so, it returns, not 1 as before, but the accumulator which at this point has the complete answer. The call chain then just rewinds back to the initial entry point in the non-recursive routine. There are no further calculations to be made as the answer is calculated on the way down rather than on the way up.
If you walk though it, the answer with standard recursion was reached by the sequence 15*14*13*...*2*1. With tail recursion, the answer was reached by the sequence 1*15*14*...*3*2. The final answer is, of course, the same. However, in my test with an initial value of 15, the standard recursion method took an average of 0.044 msecs and the tail recursion method took an average of 0.030 msecs. However, almost all that time difference is accounted for by the fact that I have the bounds checking in my standard recursion routine. Without it, the timing is much closer (0.036 to 0.030) but, of course, then you don't have error checking.
Not all recursive routines can use tail recursion. But then, not all recursive routines should be. It is a truism that any recursive function can be written using a loop. And generally should be. But a Factorial function like the ones above can never exceed 19 levels so they can be added to the lucky few.
The problem with recursion is that to understand recursion you must first understand recursion.
A recursive function is a function which calls itself, or calls a function which ultimately calls the first function again.
You have the recursion part right, since your function calls itself, and you have an "escape" clause so you don't get infinite recursion (a reason for the function not to call itself).
What you are lacking from your example though is the actual operation you are performing.
Also, instead of passing a counter, you need to pass your counter and the value you are multiplying, and then you need to return said multiplied value.
public static long recFact(int n, long val)
{
if(n==1)
{
return val;
}
else
{
return recFact(n-1, val) * n;
}
}