in the following example program in Java, I get infinite loop, and I cannot understand why:
public class Time {
public static int next(int v) {
return v++;
}
public static void main(String[] args) {
int[] z = {3, 2, 1, 0};
int i = 1;
while(i < 4) {
System.out.println(z[i]/z[i]);
i = next(i);
}
}
}
In the while-loop the method next() is invoked, and i should be incremented every time by 1: next() should return i++, and the value of i in the while loop should be incremented by one.
Why could be the reason for the infinite loop?
Thank you.
You use post incrementation.
That should work:
public static int next(int v) {
return v+1; //or ++v
}
so basically, your next function in your example, returns the same number, not incremented one.
The definition for v++ is:
Return the current value of v then add one to v
In your case, v is the method parameter which is a copy of the variable i in main, so the method just returns the same value that was passed to it. The incremented value in v is never used.
You could have used ++v. The definition of that is:
Add one to v, then return the new value
The difference here is postfix vs prefix operators.
for example:
int a = 1;
int b = a++; // sets b to to 1 THEN increments a.
// a now equals 2.
int c = ++a; // increments a THEN stores the value in c, c = 3.
calling a method which returns int++ will not do what you expect. It is not the same as having this:
while (expression) {
// code...
intValue++;
}
because in the code block above, the increment is not being passed into a seperate variable, and the full incrementation of the value will occur prior to exiting the code block, postfix or prefix form.
public static int someMethod(int n) {
return n++;
}
whereas the codeblock above will return n, then increment it later. But since your code will keep giving the same value to int n, it will keep giving the same value back since it is not incrementing your value, but rather the variable local to that method, n. Every time you pass a new value though, n is reset and will return the same thing, resulting in your infinite loop.
Is there a reason you're not using the more idiomatic and easier to read:
for(int i = 0; i < 4; i++){
System.out.println(z[i]/z[i]);
}
... or even:
for(int x : z){
System.out.println(x / x);
}
... ?
public static int next(int v) {
return ++v;
}
Don't forget arrays start with index zero in Java and division through zero throws an exception.
You should use
public static int next(int v) {
return v + 1;
}
Using v++ is wrong, as the returned value is the original value of v before incrementation.
Furthermore, using ++v or v++ in the return statement is bad style, because ++ has the side effect of modifying v, and there shouldn't be any side effects in expressions. Side effects should only be done in statements of their own to avoid confusion and undefined order of evaluation.
post increment work that sure but u ll get exception bcas of using '0' value in array . logically 0/0 is not possible its infinite so exceptio occur avoid dividing by '0' value
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);
}
}
For my homework, I am required to use a function called wrapper function to validate the parameter for a recursive function, which I don't understand what it means. All i understand from wrapper function is it does nothing but just wraps around a function eg:
private static int recursive(int n){
//do something
.
.
.
}
public static int recursiveWrap(int n){
return recursive(n);
}
I dont even know if the code above is the correct implementation for wrapper, but I know that it does nothing for the recursive function but just redundancy.
How am I supposed to use the wrapper function to validate the parameter? my recursive function has a base case which it will reach without the help of wrapper.
Well, a wrapper function would serve a purpose (otherwise there would be no reason for it to exist).
One such purpose could be to first validate the input before calling the actual recursive function (as is the case in your example), e.g. like this:
public static int recursive(int n){
//do something
.
.
.
}
public static int recursiveWrap(int n){
if( n < 0 ) {
throw new IllegalArgumentException("only positive arguments are allowed");
}
return recursive(n);
}
Another purpose could be to provide a convenient entry point for recursion, e.g. for quicksort (I'll just use int[] for simplicity reasons, a real world example would more likely use generic arrays or lists):
private static void recursiveQS(int[] array, int left, int right) {
//actual implementation here
}
//that's what the user would call
public static void quickSort(int[] array) {
recursiveQS(array, 0, array.length);
}
Why would you want to use wrapper functions? There are multiple possible reasons:
Keep the recursive function as simple as possible.
Validation checks often need to be done once so doing it in the recursive function would execute unnecessary code (and thus result in lower performance).
Provide a simple entry point for callers and handle any parameter mapping, setup etc. in the wrapper.
For more general purpose recursive functions there might be special validation or setup that only applies to certain situations and types of parameters. In those cases you might want to provide special wrapper functions for the special cases, i.e. you again keep the recursive function as simple as possible.
You are in the right direction.
Before calling the existing recursive method, you need to validate the parameter and take some action if the parameter is invalid
You haven't given the details on what to validate.
Example: If the parameter n should be within 1 to 10, you can add an if check to do that validation
public static int recursiveWrap(int n) {
if (n < 0 || n > 10) {
//some action
}
return recursive(n);
}
some action - can be anything like throwing an exception or returning a default result (maybe after logging a warning message).
In Java, usually a IllegalArgumentException is thrown to denote the argument passed is invalid.
if (n < 0 || n > 10) {
throw new IllegalArgumentException("The parameter value must be between 1 and 10 (inclusive)");
}
From my quick research on the subject, it seems the goal is to have a function validate the integer before calling the recursive function to avoid errors. For example, if I was writing a recursive function for calculating the factorial of an integer, I would want to make sure the integer is positive or zero before calling my method.
public int factorial(int n)
{
if(n == 0)
{
return 1;
}
return n * factorial(n-1);
}
public int factorialWrapper(int n)
{
if(n < 0)
{
return 0;
}
return factorial(n);
}
A wrapper for a recursive function is nothing more than a function which has
the responsibility of calling a recursive function.
Why it is used:
1)For providing a user user-friendly way of using the recursive function (since the parameters of a recursive function can be sometimes cryptic for the user and they have default values which make the function work for the most time)
2)For validation.
The following example will display all possible combinations of {0, 1, 2, 3}
in a length of 4. The function backtracking() is a wrapper for back(int)
I have written the following code in C++, if you want to translate it into java just
replace the two functions with static functions in your Java main class, replace cout with System.out.println();, remove the #include directive and `using namespace std;
and it will work;
#include<iostream>
using namespace std;
int a[4];
void back(int i)
{
if(i == 4)
{
for(int j = 0;j < 4;j++)
cout << a[j] << ' ';
cout << endl;
}
for(int j = 0; j < 4; j++)
{
a[i] = j;
back(i+1);
}
}
void backtracking() {
back(0);
}
int main() {
backtracking();
return 0;
}
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.
public class TestReturn {
int i = 0;
public static void main(String[] args) {
TestReturn t = new TestReturn();
System.out.println(t.test());
System.out.println(t.i);
}
private int test() {
return i++;
}
}
output
0
1
My question is,
Since return value of test() is 0, i,e un-incremented, so when i print i why it is incremented. What i know is, return is the exit point of method but from this method i found that there is something happening after returning from method.
So how exactly return works?
Simple.
When you do return i++ i is initially 0. The i++ is called the post-increment and as its name says i will be incremeneted after.
Although i++ returns a value before incrementing, the method finishes this statement before heading back to main. A return won't abruptly stop this statement halfway(evaluating but not incrementing)
So you'll return 0, increment it, and then see 1 when calling System.out.println(t.i);.
Technically, the value of i is stored onto the stack, the class field is incremented, and then the copied-out values of i is returned.
It's not the return that's the problem here, it's your usage of the post-increment operator.
What happens with "return i++;" is that the value of i is returned, then the value is incremented. That's why you get 0 and 1 as the values.
The sequence of actions in executing the statement return i++; is as follows.
Evaluate the expression i++.
a. Take the value of i
b. Increment the variable.
Return the value of the expression produced by step 1.
The evaluation of the expression is completed (including the increment) within the method call ... before the call returns.
Since return value of test() is 0, i,e un-incremented, so when i print i why it is incremented.
As you can see from my explanation above, that is because i was incremented as part of the expression evaluation; step 1b.
If u wanna return 1, give return ++i;
return i++; will first return i, then increment it;
i++ can be imagined as another function like (the syntax not applicable to java tough)-
preIncrementFunction(int &i){
int j = *i;
*i = *i+1;
return j;
}
so, the value getting printed is the un-incremented value of i but the value of i has changed.
I am trying to return a double from a simple for loop. For some reason I keep getting a error message saying the method is missing a return statement.
Here is my code:
public static double quantitytable(){
for(double x=1; x<=1000; x=x+100){
return x;
}
}
Your loop does not make sense: as soon as you return, looping is over. Essentially, your program is equivalent to this:
public static double quantitytable(){
return 1;
}
If you would like to return multiple items from a method, return an array or a Java collection:
public static List<Double> quantitytable() {
List<Double> res = new ArrayList<Double>();
for(double x=1 ; x<=1000 ; x += 100) {
res.add(x);
}
return res;
}
In Java, every code path has to return a value. The compiler doesn't try to prove that the for loop returns in all cases (even though we can tell it does), and thus it thinks that control could go past the end of the for loop (so it demands a return statement after the for loop).
your code will return straight away you know. while its in the first iteration
double x=1
for(; x<=1000; x+=100){
return x;}
}