Call a method or function from itself? - java

I am not able to understand how this will work as printAll is called from itself and calling in a for loop so how this function will reach at end. as when we call printAll from the for loop it will go and start the method again without ending it and then again comes to for loop and call printAll method without ending it and it will continuos do this, so can anyone explain how this funtions will work. because I am not able to understand this phenomenon.
private void printAll(Integer u, Integer d, List<Integer> savearray) {
if (u.equals(d)) {
this.saveinlist = new ArrayList<Integer>(savearray);
return ;
}
for (Integer i : adjList[u]) {
savearray.add(i);
printAll(i, d, savearray);
savearray.remove(i);
}
}

This is a Recursive method. In a recursive method there are two parts.
1. Base condition
2. Recursive part
Base condition is which when we want to stop this recursive calling.
In recursive part it called it self with some arguments. Because we have to use same set of codes to get our result.
https://www.geeksforgeeks.org/recursion/ go to this link if you know more about

Related

How to break from multiple instances calls of a recursive function?

I am creating a recursive function that will find the path between two nodes in a graph. The path will only be found if a node is not duplicated. If a node is connected to two other nodes two instances of the recursive function will be created. If there is a correct path from both of them the last found path will be set instead of the first one (line this.nodePath = clonedNodePath;). How can I break from all recursive calls when a path is found and not only break from the current recursive call instance? (I don't want to throw an exception)
private void process(String currentNodeId, List<String> currentNodePath) {
FlowNode currentFlowNode = modelInstance.getModelElementById(currentNodeId);
List<String> clonedNodePath = new ArrayList<>(currentNodePath);
if (currentFlowNode == null || clonedNodePath.contains(currentNodeId)) return;
clonedNodePath.add(currentNodeId);
if (currentNodeId.equals(finishNodeId)) {
this.nodePath = clonedNodePath;
return;
}
currentFlowNode.getOutgoing()
.stream()
.forEach(sequenceFlow -> process(sequenceFlow.getTarget().getId(), clonedNodePath));
}
The main problem lies in the iteration over the outgoing egdes.
You chose to do it with a Java8 stream, and this doesn't allow you to do an early abort (nitpicking: you can work around that "limitation", but that's clumsy).
Change that to a classical for loop, and your problem mostly disappears. Have your process() method return a boolean success indication, and inside the loop, if it gives true, return true out of this process() recursive call.
Or even more elegant: have the process() method return an Optional<List<String>>, either empty in case of failure, or filled with the path if successful. Then you also get rid of communicating via this.nodePath. And the process() method would better be named findPath().
P.S. I know it's en vogue to use streams, but there are situations where they're simply not the appropriate tool.

Java Recursive function sometimes working

I've called upon what I've learned so far and still can't fix this so decided to come here.
A BasicBlock object is referenced by an integer and holds references to the 'addresses' of more blocks in a list. I want to obtain the addresses that they hold reference to and i thought to do this recursively. It is possible for one BasicBlock to hold reference to 0 or more other blocks.
The below recursive function getFunctionReferences keeps returning a stack overflow error, yet manages to work sometimes.
Map<Integer,BasicBlock> blockList blockList = new TreeMap<Integer,BasicBlock>();
public HashSet<Integer> getAssociatedAddresses(int function) {
HashSet<Integer> blockAddresses = new HashSet<Integer>();
getFunctionReferences(this.blockList.get(function),blockAddresses);
return blockAddresses;
}
private void getFunctionReferences(BasicBlock block, HashSet<Integer> blockAddresses){
for (int x : block.getAddressReferenceList()) {
blockAddresses.add(x);
getFunctionReferences(this.blockList.get(x), blockAddresses);
}
}
I know that I am doing something wrong with this call, especially as there is no base case. But I don't know how to deal with recursion when it is in a loop like this....nor do I know a suitable base case.
Help massively appreciated.
Thanks
If you have cycles (for example block 1 references block 2 which references block 3 which references block 1), you'll get infinite recursion leading to StackOverflowError.
To avoid that, you can take advantage of the HashSet of visited blocks which you maintain. You can simply check if a block was already visited and avoid making another recursive call if it was:
private void getFunctionReferences(BasicBlock block, HashSet<Integer> blockAddresses){
for (int x : block.getAddressReferenceList()) {
if (blockAddresses.add(x)) { // only make a recursive call if x wasn't already
// in the Set
getFunctionReferences(this.blockList.get(x), blockAddresses);
}
}
}

Printing String in reverse using three pre-given methods?

I need to write a printBackwards() method, using three pre-given methods first, rest and length. printBackwards() method needs to take String as a parameter and prints each letter of that string on the console, but each letter needs to be printed on new line and in reverse order. So if the String is House, the output should be:
e
s
u
o
H
In this exercise, we should use recursion and if-else statements. No arrays, no other (familiar) String method, no while and for loop.
I have done a little bit, I know it is not correct, but that is how much I managed to do. I dont understand how to write code so the method can return letters before letter e. How to use recursion here ?
public class Recurse {
public static void main(String args[]){
System.out.println(printBackwards("House"));
}
//printBackward: takes a String as a parameter and prints letters of the String,
// one on each line, but backwards
public static String printBackwards(String s){
if (length(s) == 1){
return s;
} else {
return printBackwards(rest(s));
}
}
// first: returns the first character of the given String
public static char first(String s) {
return s.charAt(0);
}
// last: returns a new String that contains all but the
// first letter of the given String
public static String rest(String s) {
return s.substring(1, s.length());
}
// length: returns the length of the given String
public static int length(String s) {
return s.length();
}
}
Because this is a homework question, I'll leave as much as possible to you, so you learn.
Consider these two facts:
You must print the first character after you have printed the rest
If the string is empty, print nothing
Use these two facts are enough to build a recursive method.
Point 2. is the terminating condition. It's best to code this first.
Point 1. is the main method body, where printing the rest is done using recursion
Once you have your terminating condition and your recursive structure (often, a pre-order or a post-order operation), you can build a recursive method.
Note also the name of the method printBackwards() (not backwards()). That is, the method does the printing; it doesn't return the String backwards.
So, translating the above into pseudo-code (which in this case is practically the code):
if the string is empty do nothing
call self with the rest of the string
print the first character
First of all you need to print the output within the printBackwards function, so the main will look like this:
public static void main(String args[])
{
printBackwards("House");
}
Second, is the way recursion works. If you want it to be executed in the ascending order, you should do stuff before the self function call. Otherwise, in case of descending execution order, you code should be executed after the self calling function. These are the basic principles of the recursion function.
In this case, let's try to build the answer.
First, we need to handle the stop condition, which should be always written before the self calling function. The best and most common stop condition, is to reach to the end of something, in this case it is when we get an empty string, in all other cases we need to call the self function with a slight of a change, in this case it will be providing the rest of the string to the function:
if ( !length(s) )
{
//stop the recursion
return;
}
else
{
printBackwards(rest(s));
}
When you reach the stop recursion statement, from this point and on, it will close all the opened self function executions, therefor will go backward.
This is the perfect state of what we need to achieve, print the letters backward and because on each state of the printBackwards execution, we have sliced the string a bit from the left letters, it means that the first letter is the one we need.
For example, in case of the string House the last call of the printBackwards function will be when the s variable will hold the e value, because it is one stem from being cut-off to an empty string, when we reach the stop condition. In this case we want to print it out, but in the self call before this one, the s variable will hold the value se, because it is one step before cutting the first letter. So, we not want to print the whole value, but only the first letter of it, like this:
System.out.println(first(s));
Combining everything together, will result the following implementation:
public static String printBackwards(String s)
{
if ( !length(s) )
{
//stop the recursion
return;
}
else
{
printBackwards(rest(s));
System.out.println(first(s));
}
}
Hope, I explained it clearly.
Good luck!

What keywords should I use in a for-loop when using if-statements?

Let's assume that we have a for-loop that will loop through a collection or array of Strings. In that case, I am searching for a specific keyword (ex. hey) here's how I usually achieve that:
for (String result : strings)
{
if (result == "hey")
{
// Do something with that.
break;
}
}
Now, the question arises from that code snippet is, should I place a keyword (return or break) when the if-statement returns true so the loop will not continue? If not, what will happen and what's the correct way of going about it.
Edit: What happens when you use break and return? What's the difference?
Let's put your code inside a method:
private void foo()
{
for (String result : strings)
{
if (result.equals("hey"))
{
// Do something with that.
break;
}
}
bar();
}
If you use break;, the loop will terminate and bar will be reached. If you use return, the method will terminate and bar won't be executed.
Note that comparing strings should be done using equals, == compares references and not content.
If you know the word can only be found once you can surely place an break; statement so the loop won't continue after finding the match.
If you can have more than one match and you want the if block to be executed for each of those matches you should NOT put the break statement since it will stop the execution of the loop after the first match is found.

Java: Return in a for loop

Is there a way to return some value from within a for loop without jumping out of the loop?
I am implementing a static analysis tool where I have to analyze a list of methods (CFGs) in a for loop. The size of CFG list is not known in advance. Each method in the for loop has to return some value. As asked above, is there a way to do it in a loop without breaking the loop? One possible alternative comes in mind is that I can unroll the loop, assuming the maximum list size could be some fixed value. But this does not solve the problem completely. Any help would be appreciated.
code looks like below.
for(CFG cfg: cfgList)
{
val = analyze(cfg);
return val; //I want for loop not to stop here.
}
P.S. I cannot store the values in a list to return values later.
Edit1:
For example, consider following statements.
call method1();
st2;
st3;
...
This method1() can be any of five different methods. For all five possible options, I want to analyze each of them, return their values and analyze rest of the statements accordingly. So, I would analyze these 5 methods as below.
call method1-option1();
st2;
st3;
...
call method1-option2();
st2;
st3;
...
call method1-option3();
st2;
st3;
...
Hope, it helps in understanding the question.
No you can not return value from loop without jumping out of it. According to your need you have to save value in other list and you can return that list after finishing the loop.
In Java 8, you can do:
Iterator<AnalysisResult> lazyAnalysisResults = cfgList.stream()
.map(cfg -> analyze(cfg))
.iterator();
And then the Iterator will supply new analyzed results one at a time, without you needing to collect them all into a list first.
Prior to Java 8, if you want your transformation to be lazy, the best you can do is to implement an Iterator yourself:
public final class AnalyzingIterator extends Iterator<AnalysisResult> {
private final Iterator<CFG> iter;
public AnalyzingIterator(Iterator<CFG> iter) {
this.iter = iter;
}
#Override public boolean hasNext() {
return iter.hasNext();
}
#Override public AnalysisResult next() {
return analyze(iter.next());
}
#Override public boolean remove() {
throw new UnsupportedOperationException();
}
}
If you don't want to store results in a List and return it all together you can use callback mechanism.
Use analyze() to start a new thread passing cfg as well as reference to this. When processing is over make that processing thread call a callback method on your current instance / thread passing the analyzed value. Continue to do whatever you intend to do with this returned value in the callback method. And you don't have to alter your for loop.

Categories