Recursion in Java - print string permutations - java

I'm trying to write a method that prints all of the permutations of a string using recursion. For now, I have this code that works:
private static void printPermutations(String in, String out) {
if (in.length() == 0) System.out.println(out);
else {
for (int i = 0 ; i < in.length() ; i++) {
printPermutations(in.substring(0, i) + in.substring(i + 1), out + in.charAt(i));
}
}
}
It prints the right result, but I'm trying to solve it without using loops at all, including the one in line 4. Is it possible? If so, how would you solve it? Thank you!
I tried to add a third parameter called index and write index+1 inside the recursive call in line 5 but it didn't work. I think adding the third parameter is a good idea, I'm just not sure how to use it.

So I am not sure why you are trying to do that.. this is kind of the setup you would be doing for recursion, you need to not return void otherwise it's not really recursion. w3schools is a good resource.
public class Main {
public static void main(String[] args) {
int result = sum(10);
System.out.println(result);
}
public static int sum(int k) {
if (k > 0) {
return k + sum(k - 1);
} else {
return 0;
}
}
}
This would return something like
10 + sum(9)
10 + ( 9 + sum(8) )
10 + ( 9 + ( 8 + sum(7) ) )
...
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + sum(0)
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
I hope that kind of helps you put together what you need. You have to have a return so the Recursive method can see its previous call, it takes information then like a rubberband once it reaches a certain point it returns all of your iterations. Personally, I like loops more, easier to read and easier to code.
An implementation for what you are trying to do would be:
public class Main {
public static void main(String[] args) {
String result = Variations("test");
System.out.println(result);
}
public static String Variations(String k) {
if (k.length() > 0) {
return k + k.substring(0, k.lenth() - 1);
} else {
return "";
}
}
}
That would be the variation of what you are looking to do I believe.

Related

Java Recursion Scope Variable

I was looking for a program to generate balanced parentheses for given n pairs. Link: https://leetcode.com/problems/generate-parentheses/
for the solution, I found that in the below code
public void P(List<String> list, int openB, int closeB, String output, int n) {
if (output.length() == 2 * n) {
list.add(output);
return;
}
if (openB < n) {
String op1 = output + "(";
// openB=openB + 1;
//P(list, openB, closeB, op1, n); using this is giving different output.
P(list, openB + 1, closeB, op1, n);
}
if (closeB < openB) {
String op2 = output + ")";
P(list, openB, closeB + 1, op2, n);
}
}
Here using
openB=openB+1; is giving a different result as compared to passing the value in the method itself
Well, when you pass openB + 1 as an argument, it doesn't change local openB variable. On the other hand, when you do openB = openB + 1 it does change its value, and, since we use it later in method (in closeB < openB branch), program could behave differently.

Java beginner question: Method for finding next available ID in an ArrayList

ive been given this Exercise: Make a method for finding the next available member ID in an ArrayList of member objects. I create the member ID's manually when creating a new member, and i can always assume that the members have been arranged in order by ID.
For example: If i have 4 members with ID's from 0-3, and i remove the 2nd member, the method should return 1.
Here is the messy part i have for now:
public int getNextID (){
int i;
for(i = 0; i < members.size(); i++){
if(i == members.get(i).getID()){
i++;
}
else if(i != members.get(i).getID()){
System.out.println("Next available ID: " + i);
} else {
System.out.println("Next available ID: " + members.size());
break;
}
}
return i;
}
This solution provides a new Member ID from a List, where all MemberItems are sorted by ID. Item 0 in the List, must have the ID 0. Item 1 -> ID 1.
The new ID will always be the lowest available ID which is currently not assigned.
Solution 1
public int getNextID (){
for(int i = 0; i < members.size(); i++){
if(i < members.get(i).getID()){
System.out.println("Next available ID: " + i);
// at this point we know this is the next id.
// we can leave the method and return the next ID.
return i;
}
}
// we did not leave the loop (and method), because all id's are assigned.
System.out.println("Next available ID: " + members.size());
return members.size();
}
Solution 2 (Java 1.8+ Stream)
If you prefer a 2 line java 8 stream solution you could also use this:
public int getNextID() {
Member m = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().orElse(null);
return (m != null ? members.indexOf(m) : members.size());
}
Solution 3 (Java 1.8+ Stream)
or a 1 line stream solution:
public int getNextID() {
return members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().map(m2 -> members.indexOf(m2)).orElse(members.size());
}
To say something about your code:
You are increasing i twice.
Once in the for statement at the end with i++ and two lines below with i++ again.
This way, you are skipping the index 1. if the first member has the same id like index.
Timings and testing
For anyone who is interested into the comparision of timings between the 3 solutions. This are the Timings from my maschine with java1.8:
|----------------------------------------------------------------------|
| 10000 Items, Free Position 9998 | 10000 Items, Free Position 1 |
|----------------------------------------------------------------------|
| Solution1: ~2ms | Solution1: ~0.005ms |
| Solution2: ~65ms | Solution2: ~0.05ms |
| Solution3: ~60ms | Solution3: ~0.06ms |
|----------------------------------------------------------------------|
Code to execute it on your maschine. will definitly result in different timing results, but the proportion should stay about the same.
import java.util.ArrayList;
import java.util.List;
public class Test {
private static List<Member> members = new ArrayList<>();
public static void main(String[] args) {
members = getTestList(10000);
warmUp();
members.remove(9998);
testSolutions();
members.remove(1);
testSolutions();
}
private static void warmUp() {
for (int i = 0; i < 5; i++) {
for (Member m : members) {
// warm up cpu for iteration
}
members.forEach(Member::getID);
}
}
private static void testSolutions() {
long start = System.nanoTime();
int result1 = getNextID();
System.out.println("#1 Iterative result: " + result1 + " | in " + (System.nanoTime() - start) / 1000000.0 + "ms");
start = System.nanoTime();
Member m = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().orElse(null);
int result2 = m != null ? members.indexOf(m) : members.size();
System.out.println("#2 Stream Result: " + result2 + " | in " + ((System.nanoTime() - start) / 1000000.0) + "ms");
start = System.nanoTime();
int result3 = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().map(m2 -> members.indexOf(m2)).orElse(members.size());
System.out.println("#3 Stream Result: " + result3 + " | in " + ((System.nanoTime() - start) / 1000000.0) + "ms");
}
private static int getNextID() {
for (int i = 0; i < members.size(); i++) {
if (i < members.get(i).getID()) {
return i;
}
}
return members.size();
}
private static List<Member> getTestList(int count) {
List<Member> members = new ArrayList<>();
for (int i = 0; i < count; i++) {
members.add(new Member(i));
}
return members;
}
private static class Member {
private int id;
public Member(int id) {
this.id = id;
}
private int getID() {
return id;
}
}
}
For List, use size() to get the number of elements.(also it's give you the last but 1 index used).
Index is starting from 0 and is automatically adjusted when adding or removing elements.
So you do not need to keep tracking manually for indexes.
Note, when you add on list with method add(index, element) index should always be less then or equal to size()_methods return.
List<String> l = new ArrayList<String>();
l.add("a"); //auto index 0
l.add("b"); //auto index 1
l.add("c"); //auto index 2
System.out.println(l.size()); //3 and it's also next_available for add at bottom
l.remove(1);
l.forEach(System.out::println); //a c
System.out.println(l.size()); // 2
System.out.println(l.get(0)); //a
System.out.println(l.get(1)); //c adjusted index from 2 to 1 after remove
l.add(2,"d");
System.out.println(l.size()); //3
l.add(4,"e"); //error java.lang.IndexOutOfBoundsException: Index: 4, Size: 3
Kindly see #Sunchezz and #Evan answers for a full solution.

Learning Java (and Programming) on Udemy. Need help to understand logic

I am currently watching a video on recursion, and I need some help with the logic in it.
I don't understand the return "moment" of the algorithm.
Here is the code:
public class App {
public static void main(String[] args) {
// E.g. 4! = 4*3*2*1 (factorial 4)
System.out.println(factorial(5));
}
private static int factorial(int value) {
//System.out.println(value);
if(value == 1) {
return 1;
}
return factorial(value - 1) * value;
}
}
What I don't understand is the return 1; part.
When the method is calculating the factorial of 4, it recalls it self until value becomes 1.
But when value == 1, the method is supposed to return 1 to the caller of the method.
Doesn't this return 1 overrides return factorial(value - 1) * value;??
Clearly, I don't completely understand how return works.
Thanks in advance :)
The point of every recursion is "stop point", the condition, when recursion does not continue, but instead returns value. If this point does not exist, the recursion nevers ends.
This is how it will be called :
System.out.println(factorial(5))
-return factorial(4)*5
--return factorial(3)*4
---return factorial(2)*3
----return factorial(1)*2
-----return 1
----return 1*2
---return 2*3
--return 6*4
-return 24*5
System.out.println(120)
I think it is more clear, when you put "return" outside the recursive counting, because you are doing more stuff in one line.
I made this program, ignore "doMinuses" method, it only makes minuses to make output more readable. It does the same thing as your program. You do not have to read it, just look to output first.
public class App {
public static int origValue = 5;
public static void main(String[] args) {
System.out.println(factorial(origValue));
}
private static int factorial(int value) {
doMinuses(origValue-value);
System.out.println("Entered factorial("+value+")");
if(value == 1) {
doMinuses(origValue-value);
System.out.println("Returning 1");
return 1;
}
doMinuses(origValue-value);
System.out.println("Start countin factorial("+(value-1)+")*"+value);
int factorialResult = factorial(value - 1) * value;
doMinuses(origValue-value);
System.out.println("Returning result for factorial("+(value-1)+")*"+value + " = " + factorialResult);
return factorialResult;
}
private static void doMinuses(int count){
for (int i = 0; i < count; i++) {
System.out.print('-');
}
}
}
The output is
Entered factorial(5)
Start countin factorial(4)*5
-Entered factorial(4)
-Start countin factorial(3)*4
--Entered factorial(3)
--Start countin factorial(2)*3
---Entered factorial(2)
---Start countin factorial(1)*2
----Entered factorial(1)
----Returning 1
---Returning result for factorial(1)*2 = 2
--Returning result for factorial(2)*3 = 6
-Returning result for factorial(3)*4 = 24
Returning result for factorial(4)*5 = 120
120
The only difference outside printing out code is to change this line
return factorial(value - 1) * value;
to two lines, because it is, what is really happening (especially the order of what is happening).
int factorialResult = factorial(value - 1) * value;
return factorialResult;
I edited function even more for BEST output ever :)
public class App {
public static int origValue = 5;
public static void main(String[] args) {
System.out.println(factorial(origValue));
}
private static int factorial(int value) {
doMinuses(origValue - value);
System.out.println("Entered factorial(" + value + ")");
if (value == 1) {
doMinuses(origValue - value);
System.out.println("Returning 1");
return 1;
}
doMinuses(origValue - value);
System.out.println("Start countin factorial(" + (value - 1) + ")*" + value);
int factorialResult = factorial(value - 1);
doMinuses(origValue - value);
System.out.println("Finished counting factorial(" + (value - 1) + ") = " + factorialResult);
doMinuses(origValue - value);
System.out.println("Returning result for factorial(" + (value - 1) + ")*" + value + " = " + factorialResult + "*" + value + " = " + (factorialResult * value));
return factorialResult * value;
}
private static void doMinuses(int count) {
for (int i = 0; i < count; i++) {
System.out.print('-');
}
}
}
Has this output :
Entered factorial(5)
Start countin factorial(4)*5
-Entered factorial(4)
-Start countin factorial(3)*4
--Entered factorial(3)
--Start countin factorial(2)*3
---Entered factorial(2)
---Start countin factorial(1)*2
----Entered factorial(1)
----Returning 1
---Finished counting factorial(1) = 1
---Returning result for factorial(1)*2 = 1*2 = 2
--Finished counting factorial(2) = 2
--Returning result for factorial(2)*3 = 2*3 = 6
-Finished counting factorial(3) = 6
-Returning result for factorial(3)*4 = 6*4 = 24
Finished counting factorial(4) = 24
Returning result for factorial(4)*5 = 24*5 = 120
120
Return 1 does override the return factorial(value - 1) * value;
But what this function is doing is calling itself, up until the value hits 1.
Once the value hits one, the if condition is met and the return 1 part is called, completely ending the function (kind of like a break; would, to put it simply), so it will stop executing the return factorial(value - 1) * value;
Returned value '1' comes from this expression
return factorial(value - 1) * value;
and is used only here, previous lines will never be evaluated.
In this case, recursion works similarly to a loop. To understand how it works, you may use debugger, or try to write down each instruction (statement, expression) in order in which it will be evaluated.
for factorial(3)
it will look like this
factorial(3)
if(3==1) //false
factorial(2) //to return factorial(2) * 3 when function becomes evaluated
if(2==1) //false
factorial(1) // //to return factorial(1) * 2 when function becomes evaluated
if(1==1) //true
return 1;
return /*factorial(1) = */ 1 * 2;
return /*factorial(2) = */ 2 * 3; //return 6 - result of your top call of factorial(3) from the main call

Return statement best practices in java?

I want to know the difference between these two codes even though they produce the same output:
CODE 1:
class ret {
public static int add(int x) {
if(x!=0)
return x+add(x-1);
return x;
}
public static void main(String args[]) {
System.out.println(add(5));
}
}
CODE 2:
class ret {
public static int add(int x) {
if(x!=0)
return x+add(x-1);
return 0;
}
public static void main(String args[]) {
System.out.println(add(5));
}
}
They both output 15 but how come the second code also output's 15 instead of zero?My understanding is that the last call would be add(0) for code 2 and it would return zero.I also want to know is it okay to use multiple return statements or use a single return statement and replace the rest with local variables.I remember reading that single entry single exit model is a good practice.
This is a recursive method, so when x != 0, you will return the result of "x added to calling the method again with (x-1)". The final call will always return x == 0 or constant = 0, so you will return 15 from both versions.
Single return vs. multiple return is a matter of debate. The former should be preferred as a rule. Generally it will be obvious where multiple return statements are acceptable as it will be simpler to understand the method with them than with the alternative code constructs required to engineer a single exit point. Also note you could rewrite add as:
public static int add(int x) {
return x == 0 ? 0 : (x + add(x-1));
}
Version 1:
add(5)
call add(4)
call add(3)
call add(2)
call add(1)
call add(0)
return (x = 0)
return (x = 1) + (add(x-1) = 0) = 1
return (x = 2) + (add(x-1) = 1) = 3
return (x = 3) + (add(x-1) = 3) = 6
return (x = 4) + (add(x-1) = 6) = 10
return (x = 5) + (add(x-1) = 10) = 15
Version 2:
add(5)
call add(4)
call add(3)
call add(2)
call add(1)
call add(0)
return (constant = 0) // the only difference
return (x = 1) + (add(x-1) = 0) = 1
return (x = 2) + (add(x-1) = 1) = 3
return (x = 3) + (add(x-1) = 3) = 6
return (x = 4) + (add(x-1) = 6) = 10
return (x = 5) + (add(x-1) = 10) = 15
The use of multiple return statement versus using a single exit point cannot be answered with an easy one-line answer. I guess the best answer you can get is "it depends on your company's standards".
Single exit point is a very good standard, even though I don't personally endorse it. You end up having methods that always have a single return statement at the end, so you never get in a position where you are looking for those many possible return statement while editing someone else's code. I believe that developers that used to code in C tend to follow this standard (see this question).
I, for one, perfer using multiple return statements when it can help simplify the code. One case where I like to use it is to prevent cascading braces in my code. For instance, in the following example:
private int doSomething (int param) {
int returnCode;
if (param >= 0) {
int someValue = param * CONSTANT_VALUE;
if (isWithinExpectedRange (someValue)) {
if (updateSomething (someValue)) {
returnCode = 0;
} else {
returnCode = -3;
}
} else {
returnCode = -2;
}
} else {
returnCode = -1;
}
return returnCode;
}
I find this type of coding to be very confusing when reading it. I tend to change this type of code to:
private int doSomething (int param) {
if (param < 0) {
return -1;
}
int someValue = param * CONSTANT_VALUE;
if (!isWithinExpectedRange (someValue)) {
return -2;
}
if (!updateSomething (someValue)) {
return -3;
}
return 0;
}
The second example looks cleaner, and clearer, to me. Even more when the actual code has some extra coding in the else blocks.
Again, this is personal tastes. Some company might enforce a single exit point, some might not, and some developers prefer single exit point. The bottom line is, if there's a guideline available for you to follow in your environment, then do so. If not, then you can chose your own preference base partly on these arguments.

Using mutual recursion to do a binary comparison of two files; would prefer to use one method, calling itself. How?

I've made a crossword (and similar) puzzle helper, which enables searching a dictionary for matches to a pattern such as pa??ern, pa*, pa??ern*, etc., where ? and * have the same meaning as wildcards in Windows (? matches any letter; * matches any number of letters [including 0]).
I found two text dictionaries online, one with 108,000+ words, the other with 80,000+. I assumed that the smaller would be a subset of the larger. Not even close.
So I wrote a Java program to compare and to print any word that is in one dictionary but not in the other. (Turned out there were 24,000+ words in the smaller than in the larger; 52,000+ in larger but not in smaller. So I now, via another program, have a dictionary with 132,000+ words.)
I used mutual recursion to accomplish this:
-When current words match, continue; nothing to print here.
-When current word from dictionary A is "<" than current word in B, then...
* print and read A until finding word ">=" current word in B.
--If '=', they match; continue without printing.
--If '>', then reverse the process:
* print and read B until finding word ">=" current word in A.
...
This is all there is to the logic. I really like recursion because it's how we think, though it's often very hard to get those thoughts into code.
And some things about the nature of programmatic recursion are very hard.
In particular, I had to use "dual" methods: one for reading A until >= B; one for reading B until >= A.
I tried to make one routine that would call itself in the same way the different routines call each other, as described above in pseudocode.
I'm asking for someone to show me how to use ONE method to call itself to accomplish the goal.
Here's the code that works but is inefficient, as described:
package filecomparison;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class ShorterBinaryCompare {
static int kta = 0, exa = 0, ktb = 0, exb = 0;
static Scanner sca, scb;
static String reca, recb;
static Path a = Paths.get("C:\\newdic.txt");
static Path b = Paths.get("C:\\WordHelp.dick");
private static int read_a_untilGE_b(){
while(sca.hasNext()){
if(reca.equals(recb)) return 0; // 0 => a = b
if(reca.compareTo(recb) > 0) break; // a > b
System.out.println(reca); exa++; kta++;
reca = sca.next();
}
read_b_untilGE_a();
return 0;
}
private static int read_b_untilGE_a(){
while(scb.hasNext()){
if(recb.equals(reca)) return 0; // a = b
if(recb.compareTo(reca) > 0) break; // b > a
System.out.println("\t\t" + recb); exb++; ktb++;
recb = scb.next();
}
read_a_untilGE_b();
return 0;
}
private static void drain(String msg, Scanner sc){
int k = 0;
System.out.println("\n\nDraining " + msg);
String s;
while(sc.hasNext()){
s = sc.next();
System.out.println(s);
++k;
}
System.out.println("\nExtras at end: " + k);
}
public static void main(String[] args) throws IOException {
System.out.println("Compare:\n" + a + " vs. \n" + b + "\n");
sca = new Scanner(a); scb = new Scanner(b);
while(sca.hasNext() && scb.hasNext()){
reca = sca.next(); kta++;
recb = scb.next(); ktb++;
int compareResult = reca.compareTo(recb);
if( compareResult < 0) read_a_untilGE_b(); // a < b
else if(compareResult > 0) read_b_untilGE_a() ; // a > b
// mutually-recursive read...untils make a = b at this point
}
System.out.println("\n\nRecords in " + a.toString() + ": " + kta);
System.out.println("Extras in " + a.toString() + ": " + exa);
System.out.println("Records in " + b.toString() + ": " + ktb);
System.out.println("Extras in " + b.toString() + ": " + exb);
if(sca.hasNext()){ drain(a.toFile().toString(), sca); }
if(scb.hasNext()){ drain(b.toFile().toString(), scb); }
}
}
Here's the last version I tried of one method calling itself. It worked as long as it was the "left" file with the extra words, but when it changed so that the "right" file had the extras, it didn't take long to get stack overflow. Maybe I'm closer than I thought; but I'm out of gas for the day.
Can you modify the method below, which calls itself, to do what mutual recursion does in the code above?
private static int read_untilGE_(Scanner a, Scanner b){
String sa, sb;
if(b.hasNext())
sb = b.next();
else
return -1;
System.out.println("Extra in " + a.toString());
while(sca.hasNext()){
sa = sca.next();
if(sa.equals(sb)) return 0; // a = b
if(sa.compareTo(sb) > 0) break; // a > b
System.out.println(sa); exb++; ktb++;
}
read_untilGE_(b, a);
return 0;
}
You got off to the right start by passing your two Scanners as parameters to your method, so that you call your method recursively by switching the parameters. Then you erred by using a Scanner (sca) that wasn't one of the parameters.
Thanks to #ajb's quick response and a good night's (... well, a few hours') sleep, I got exactly what I wanted. The fix wasn't quite as simple as changing Scanner sca to a, but it was exactly the problem that I failed to notice.
And I failed to notice it because of sloppy coding. I had too many global variables, especially sca and scb. Had they been local to main, I'd've caught the problem last night.
Here's the method that calls itself. The '--------------------' lines are the changes relative to the error in logic that ajb pointed out.
private static int read_untilGE_(Scanner a, String sa, long ma,
Scanner b, String sb, long mb){
String indent;
boolean shouldPrint;
if (ma == mapa){indent = inda; shouldPrint = showa;}
else {indent = indb; shouldPrint = showb;}
if(shouldPrint) System.out.println(indent + sa); // --------------------
while(a.hasNext()){ // --------------------
sa = a.next(); // --------------------
if(sa.equals(sb)) return 0; // a = b
if(sa.compareTo(sb) > 0) break; // a > b
if(shouldPrint) System.out.println(indent + sa);
}
read_untilGE_(b, sb, mb, a, sa, ma);
return 0;
}
And here's the rest of the program:
package filecomparison;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class BinaryCompare {
static long mapa, mapb;
static String inda, indb;
static Boolean showa = true, showb = true;
private static void drain(String msg, Scanner sc){
int k = 0;
System.out.println("\n\nDraining " + msg);
String s;
while(sc.hasNext()){
s = sc.next();
System.out.println(s);
++k;
}
System.out.println("\nExtras at end: " + k);
}
public static void main(String[] args) throws IOException {
Scanner sca, scb;
String reca, recb;
Path a = Paths.get("C:\\newdic.txt");
Path b = Paths.get("C:\\WordHelp.dick");
sca = new Scanner(a); scb = new Scanner(b);
mapa = a.hashCode( ); mapb = b.hashCode();
inda = ""; indb = "\t\t\t";
System.out.println("Extra words in:\n" + inda + " " + a + "\n" + indb + b );
while(sca.hasNext() && scb.hasNext()){
reca = sca.next();
recb = scb.next();
int compareResult = reca.compareTo(recb);
if( compareResult < 0) read_untilGE_(sca, reca, mapa, scb, recb, mapb); // a < b
else if(compareResult > 0) read_untilGE_(scb, recb, mapb, sca, reca, mapa); // a > b
// recursion makes a = b at this point
}
if(sca.hasNext())drain(a.toFile().toString(), sca);
if(scb.hasNext())drain(b.toFile().toString(), scb);
sca.close(); scb.close();
} // end main
}

Categories

Resources