Implementing recursion in Java - java

Just to be clear, this is not a homework assignment, I study CS in my own time!
I recently purchased a book entitled '50 puzzles for logical thinking' by Charles Phillips. I started one of them and it occurred to me that I could solve the problem using recursion. Here's the (paraphrased) question:
Insert a mathematical operator (+, -, ÷, x) in each of the spaces to solve the equation:
6 _ 3 _ 5 _ 7 _ 4 _ 8 = 13
It is my understanding, that in order to solve this problem using recursion, I first need to identify a base case. However, I'm having trouble doing this.
So my question is, what is a possible base case and how should I begin to implement it? What could the recursive function look like (arguments, return type etc)? (code is helpful please)!
This is what I have so far: Nearly working I think
See my answer for an implementation
N.b. I'm using Java

I think the stopping condition should mean that the equation is satisfied: all the operators filled in, and the operations resulting in a proper equality.
I would express the equation as a parse tree, with the leaves as numbers and the parents as operators. A tree naturally lends itself to recursion, because it's a hierarchical data structure.
Make an operator assumption where the root operation is the minus sign, the right child is the desired value (13), and the left child is the left hand side. Add an operator, evaluate the tree, and backtrack until your stopping condition is met.

The base case is when all the blanks are filled in with operators. You can solve this problem using depth-first backtracking search:
algorithm dfs(i):
if i == num_blanks: # base case: filled in all the blanks
if equation_solved():
return the operators you filled in
else:
for op in (+, -, ÷, ×):
blank[i] = op
if dfs(i + 1) returns a solution:
return that solution
blank[i] = _ # restore to previous state
This is a recursive way of searching through the entire combinatorial space. (I hope this doesn't spoil the exercise for you; I wrote it in pseudocode to leave the implementation to you.)

You can think of it as a tree of decisions.
6
/ / \ \
+ - * /
3 Assuming you choose + for the first operator
/ / \ \
+ - * /
5 5 5 5
^ ^
6 + 3 - 5 6 + 3 / 5
You can then use a graph traversal algorithm such as DFS or BFS to check the result. Both are naturally recursive.

Here is the implementation I ended up with, but first an explanation of the solution to the problem:
The base case (as said by larsmans and Jan Dvorak) is when all the "_" are filled with operators (such as "+").
The function calls itself, adding another parameter each time until it reaches a base case that is incorrect (e.g. "6+3+5+7+4-8=13") or it has a correct answer.
If the base case is incorrect, then we keep popping up levels we get to a level with an operator we can change.
Here's the code:
class GapFill {
private static String numbers; //E.g. 6_5_4=15
private static String[] blank; //Array of operators to go in the blanks
//Where:
//p = plus
//m = minus
//d = divide
//t = times
private static String[] operators = {"p", "m", "d,", "t"};
public static void main(String[] args) {
numbers = args[0];
blank = new String[numbers.split("_").length - 1];
if(dfs(0)) { //If a solution was found
int count = 0;
while(numbers.indexOf("_")!=-1) {
int index = numbers.indexOf("_");
numbers = numbers.substring(0,index)+blank[count]+numbers.substring(index+1);
count++;
}
System.out.println(numbers);
}
}
private static boolean dfs(int i) {
if(i == blank.length) { //base case: filled in all the blanks
return solveEquation();
}
for(String op : operators) {
blank[i] = op;
if(dfs(i + 1)) {
return true;
}
}
blank[i] = "_"; //restore to previous state
return false;
}
private static boolean solveEquation() {
String[] eachNumber = numbers.substring(0, numbers.indexOf("=")).split("_");
String finalResult = numbers.substring(numbers.indexOf("=")+1, numbers.length());
double currentResult = Double.parseDouble(eachNumber[0]);
for(int i=1;i<eachNumber.length;i++) {
String op = blank[i-1];
if(op==operators[0]) {
currentResult = currentResult + Integer.parseInt(eachNumber[i]);
} else if(op==operators[1]) {
currentResult = currentResult - Integer.parseInt(eachNumber[i]);
} else if(op==operators[2]) {
currentResult = currentResult / Integer.parseInt(eachNumber[i]);
} else if(op==operators[3]) {
currentResult = currentResult * Integer.parseInt(eachNumber[i]);
}
}
return (currentResult==Integer.parseInt(finalResult));
}
}
The output for java GapFill 6_3_5_7_4_8=13 is 6m3p5m7p4p8=13.
The "p,m,d,t" symbols are used instead of "+,-,÷,×" since the terminal doesn't like × or ÷

Related

Count the Characters in a String Recursively & treat "eu" as a Single Character

I am new to Java, and I'm trying to figure out how to count Characters in the given string and threat a combination of two characters "eu" as a single character, and still count all other characters as one character.
And I want to do that using recursion.
Consider the following example.
Input:
"geugeu"
Desired output:
4 // g + eu + g + eu = 4
Current output:
2
I've been trying a lot and still can't seem to figure out how to implement it correctly.
My code:
public static int recursionCount(String str) {
if (str.length() == 1) {
return 0;
}
else {
String ch = str.substring(0, 2);
if (ch.equals("eu") {
return 1 + recursionCount(str.substring(1));
}
else {
return recursionCount(str.substring(1));
}
}
}
OP wants to count all characters in a string but adjacent characters "ae", "oe", "ue", and "eu" should be considered a single character and counted only once.
Below code does that:
public static int recursionCount(String str) {
int n;
n = str.length();
if(n <= 1) {
return n; // return 1 if one character left or 0 if empty string.
}
else {
String ch = str.substring(0, 2);
if(ch.equals("ae") || ch.equals("oe") || ch.equals("ue") || ch.equals("eu")) {
// consider as one character and skip next character
return 1 + recursionCount(str.substring(2));
}
else {
// don't skip next character
return 1 + recursionCount(str.substring(1));
}
}
}
Recursion explained
In order to address a particular task using Recursion, you need a firm understanding of how recursion works.
And the first thing you need to keep in mind is that every recursive solution should (either explicitly or implicitly) contain two parts: Base case and Recursive case.
Let's have a look at them closely:
Base case - a part that represents a simple edge-case (or a set of edge-cases), i.e. a situation in which recursion should terminate. The outcome for these edge-cases is known in advance. For this task, base case is when the given string is empty, and since there's nothing to count the return value should be 0. That is sufficient for the algorithm to work, outcomes for other inputs should be derived from the recursive case.
Recursive case - is the part of the method where recursive calls are made and where the main logic resides. Every recursive call eventually hits the base case and stars building its return value.
In the recursive case, we need to check whether the given string starts from a particular string like "eu". And for that we don't need to generate a substring (keep in mind that object creation is costful). instead we can use method String.startsWith() which checks if the bytes of the provided prefix string match the bytes at the beginning of this string which is chipper (reminder: starting from Java 9 String is backed by an array of bytes, and each character is represented either with one or two bytes depending on the character encoding) and we also don't bother about the length of the string because if the string is shorter than the prefix startsWith() will return false.
Implementation
That said, here's how an implementation might look:
public static int recursionCount(String str) {
if(str.isEmpty()) {
return 0;
}
return str.startsWith("eu") ?
1 + recursionCount(str.substring(2)) : 1 + recursionCount(str.substring(1));
}
Note: that besides from being able to implement a solution, you also need to evaluate it's Time and Space complexity.
In this case because we are creating a new string with every call time complexity is quadratic O(n^2) (reminder: creation of the new string requires allocating the memory to coping bytes of the original string). And worse case space complexity also would be O(n^2).
There's a way of solving this problem recursively in a linear time O(n) without generating a new string at every call. For that we need to introduce the second argument - current index, and each recursive call should advance this index either by 1 or by 2 (I'm not going to implement this solution and living it for OP/reader as an exercise).
In addition
In addition, here's a concise and simple non-recursive solution using String.replace():
public static int count(String str) {
return str.replace("eu", "_").length();
}
If you would need handle multiple combination of character (which were listed in the first version of the question) you can make use of the regular expressions with String.replaceAll():
public static int count(String str) {
return str.replaceAll("ue|au|oe|eu", "_").length();
}

How can i create a recursive method that does the exp of n but returns a String n number of times in Java

So i'm doing an exercise but i'm having a bad time with recursive methods.
I want the method starPower to return the power of 2 to the n in asterisks ("*") but i get a Stack Overflow.
Can someone tell me what am i doing wrong?
Here is what i have so far:
public static String starPower(int n){
String str = "*";
if (n<0)
throw new IllegalArgumentException("n has an invalid value");
if (n==0)
{return str;
}
return str + starPower( Math.pow(2,n-1));
}
Don't use Math.pow(). Your method is supposed to be recursive and use simple operations.
I will not give you the code, but explain how it should work. First, here are the expected results:
starPower(0) = "*" // 2^0 = 1 stars
starPower(1) = "**" // 2^1 = 2 stars
starPower(2) = "****" // 2^2 = 4 stars
starPower(3) = "********" // 2^3 = 8 stars
starPower(4) = "****************" // 2^4 = 16 stars
starPower(5) = "********************************" // 2^5 = 32 stars
starPower(6) = "****************************************************************"
. . .
As you can see, the result if starPower(n) is double1 the result of starPower(n - 1). That is your simple recursion.
1) By double, I mean double the length, i.e. the string concatenated with itself.
You need to understand the pattern of the outputs in your problem to solve it.
if you can find a relation between input and output in each case of n you could solve it.this way of thinking is called Reverse Engineering.
As Andreas said in his answer from the test cases you can conclude that starPower(n) is double the result of starPower(n - 1):
starPower(0) = "*"
starPower(1) = "**"
starPower(2) = "****"
so you only need to double the result of "*" in each recursive call:
public static String starPower(int n){
if (n < 0){
throw new IllegalArgumentException("n has an invalid value");
}
if (n==0){
return "*";
}
return starPower(n-1) + starPower(n-1);
}
public static void main(String[] args) {
System.out.println(starPower(3));
}
Output:
********
You have to think recursively, which is pretty difficult. If you concatenated the results of two function calls for n-1, you'd have two halves, making a whole. Notice however that since calling the function twice with the same input would yield the same output twice. So you can help lessen the burden on the stack by only calling once and using the result twice.
Try to visualize it like this for an example of calling starPower(3). It calls starPower(2) and concatenates the result of that with itself. Calling starPower(2) calls starPower(1) and concatenates the result of that with itself. starPower(1) calls starPower(0) and concatenates the result of that with itself.
starPower(0) always returns "*"; it's the base case. You can now build up from here. starPower(1) takes two of them and pastes them together making "**". starPower(2) concatenates two of those to make "****". There's a pattern emerging for you now hopefully. Lastly, starPower(3) takes two of those and concatenates them to make the final result of "********", which is 8, or 2³, asterisks.
3: ********
2: **** ****
1: ** ** ** **
0: * * * * * * * *
Here's the modified code implementing that solution.
public static String starPower(int n) {
if (n < 0) {
throw new IllegalArgumentException("n has an invalid value");
}
if (n == 0) {
return "*";
}
String halfResult = starPower(n - 1);
return halfResult + halfResult;
}

Recursion? Combinations in a String

I've been dealing with the following recursion question for a while now and haven't been able to figure it out. Basically, you have some sort of a sentence made out of certain words, where all the words are just jammed together, not spaced out. The idea is to find the number of all possible combinations of words that can be used to create the sentence.
For example,
Words: ook, ookook
Sentence: ookookook
Solution: {ook, ook, ook}, {ookook, ook}, {ook, ookook}.
Another example:
Words: ooga, oogam, oogum, mook, ook
Sentence: oogamookoogumook
Solution: {ooga, mook, oogum, ook}, {oogam, ook, oogum, ook}
I've tried a lot of things, finally giving up and trying to do it manually...
public static int WAYS(String word) {
int ways = 1;
for (int i = 0; i < word.length(); i++) {
try{
if(word.substring(i, i - 2).equals("ug")){
if(word.substring(i - 4, i - 2).equals("ug")){
ways++;
}
}
else if(word.substring(i, i - 3).contains("ook")){
System.out.println(word.substring(i-6, i-3));
if(word.substring(i - 6, i - 3).equals("ook")){
ways++;
}
if(word.charAt(i - 4) == 'm'){
if(word.substring(i - 8, i - 4).equals("ooga") || word.substring(i - 8, i - 4).equals("oogu")){
ways++;
}
}
}
else if(word.substring(i, i - 4).contains("mook")){
if(word.substring(i - 8, i - 4).contains("mook")){
ways++;
}
}
if(word.substring(i, i - 2).equals("oog")){
if(word.charAt(i + 2) == 'm'){
if(word.charAt(i + 1) == 'a' || word.charAt(i + 1) == 'u'){
ways++;
}
}
}
} catch(Exception e){
continue;
}
}
return ways;
}
But it hasn't worked. Could somebody please give me an idea or a sample on approaching this problem using recursion?
1) Name your methods properly, "WAYS" is a constant name, not a method name.
2) Provide runnable code, especially in cases where it's so short.
3) Never use Exceptions for control flow.
4) You are using magic values like "uug" and "ook" in your code? Does this look simple and obvious? Does this look maintainable? What is this supposed to look like if you get a lexicon with a million of different words?
Edit: giving the complete listing is somehow boring, so I left a few gaps. Try to fill those, hope that helps.
public class JammedWords {
public static int ways(String sentence, String[] words) {
if (sentence.isEmpty()) {
// The trivial case: the sentence is empty. Return a single number.
} else {
int c = 0;
for (String w: words) {
if (sentence.startsWith(w)) {
// call method recursively, update counter `c`.
}
}
return c;
}
}
public static void main(String[] args) {
System.out.println(ways("ookookook", new String[]{"ook", "ookook"}));
System.out.println(ways("oogamookoogumook", new String[]{"ooga","oogam","oogum","mook","ook"}));
}
}
Hints:
A) Understand the difference between empty set, set containing the empty set, set containing a set containing an empty set etc. Sets that contain empty sets are of course not empty, and their size is not 0.
B) There is a handy method String.substring(n) that drops everything before the 'n'-th character. And there is String.length() to get size of words.
Hope VB.NET code won't mind, just for the grasp.
Private Sub Go()
Dim words As New List(Of String)
words.Add("ooga")
words.Add("oogam")
words.Add("oogum")
words.Add("mook")
words.Add("ook")
Search("oogamookoogumook", words, "", New List(Of String))
End Sub
Private Sub Search(ByVal sentence As String, _
ByVal wordList As List(Of String), _
ByVal actualSentenceBuildingState As String, _
ByVal currentPath As List(Of String))
For Each word As String In wordList
Dim actualSentenceAttemp As String
Dim thisPath As New List(Of String)(currentPath)
thisPath.Add(word)
actualSentenceAttemp = actualSentenceBuildingState + word
If actualSentenceAttemp = sentence Then
Debug.Print("Found: " + String.Join("->", thisPath.ToArray()))
End If
If actualSentenceAttemp.Length < sentence.Length Then 'if we are not too far, we can continue
Search(sentence, wordList, actualSentenceAttemp, thisPath)
End If
Next
End Sub
Printouts:
Sentence: oogamookoogumook
Found: ooga->mook->oogum->ook
Found: oogam->ook->oogum->ook
Sentence: ookookook
Found: ook->ook->ook
Found: ook->ookook
Found: ookook->ook
Think about it as walking in graph (its nothing else than that in fact). You start with nothing (empty string). Now you start to iteratively add words from wordlist into your 'current attemp for sentence'. After adding word to current attemp, you can end only in three possible states: (1) you got the final sentence, (2) current attemp is shorter than target sentence and thus still suitable for adding next words (recursion call), or (3), your current attemp is longer (or the same length but not equal) than target sequence, thus it has no meaning to continue in search with it.
What you have to remember is path -- "how did i get here?" list (back tracking).

Recursive manual way to convert int to string (without anything like an array, a list, or parsing stuff) for positive and negative numbers [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
hello i worked on a recursive method to convert from int to string fully manual way, and i wanna know if that recursive method is efficient or not, and if you could help me to improve the code. Im new to algorithms so don't blame me if something looks like ugly... I've search on the internet but never looked for something like that :
public class IntToString {
public static String intToString(int number) {
return intToString(number, "", false);
}
private static String intToString(int number, String answer,
boolean isNegative) {
if (number < 0 && isNegative == false) {
isNegative = true;
number = -number;
}
if (number == 0)
if (isNegative)
return "-" + answer;
else
return answer;
System.out.println(number);
return intToString(number / 10, answer = number % 10 + answer,
isNegative);
}
// test
public static void main(String[] args) {
String ans = intToString(-324234);
System.out.println(ans);
}
}
No, it's not very efficient. Though it could be worse. At least it's still O(N) where N is the number of decimal digits in the given number.
invertInt is not really needed. You are using it because you are appending it to the answer that you pass down the the recursions, which will cause that number to be inverted. But there are at least two other ways to do it so that it won't be inverted.
If you note, there is only a very slight difference between the the way you handle negative numbers and positive numbers. Perhaps you can just run the same procedure for both of them, if you remember that processing a negative number is the same as processing its positive opposite, and tacking the - when you're done.
There is no reason for all the flags for negative and inversion. Both of them are only done at the top level. So you can do those things at the intToString(int number) function and not in your recursive function, and save yourself a lot of condition checking, and of course, the replaceAll() call.
There is no need to pass down the answer. You can base your return value on what the recursive call returned. Remember that for numbers like 1,2,3, you'll get the string '1','2','3'. So if you have 23, and you pass down 2, you can use the 2 you got to build your answer.
Your algorithm does not return the correct answer for 0. It's the correct answer when you think in recursive terms, but not when you call it with 0 from main. There are at least two ways to handle that.
And a bit of style advice:
Always indent your code properly.
You don't need to compare boolean values to true or false. If you have a boolean variable x, you can use if (x) or if (!x) rather than if (x==true) and if (x==false). Name your boolean variables in a way that will make this more intuitive, like isNegative or needsInversion. An if (isNegative) makes sense when you read it.
More detailed information in case you could not find the solution:
How do we avoid the inversion? There are two ways, basically. If you insist on passing down the answer, then instead of:
answer += num % 10;
Use:
answer = ( num % 10 ) + answer;
That is - append it to the left of the answer, not its right.
The approach I prefer is using the answer from the lower level. Suppose you have the number 123. So you pass down 12, and you get back the answer "12". Then you can use
return answer + ( num % 10 );
which will give you "123". This time, it's appended to the right.
Finally, here is the complete solution:
public static String intToString( int n ) {
if ( n == 0 ) {
return "0";
} else if ( n < 0 ) {
return "-" + positiveIntToString( -n );
} else {
return positiveIntToString(n);
}
}
private static String positiveIntToString( int n ) {
if ( n == 0 ) {
return "";
} else {
return positiveIntToString( n / 10 ) + ( n % 10 );
}
}
You have the public function that is what you expose to the world. The recursive function is private, and it is only called for positive numbers. If called with zero, it will return an empty string, which is good for the recursion, but not as a real solution.
So the public function first checks two possible issues. If the number is zero, it shouldn't be passed to the private function because it will not return the correct answer. Instead, just return the string "0", as it is the correct answer.
For a negative number, all we need to do is do the work for its counterpart, -n, which is positive and so will be acceptable to the private function. And then we add the "-" in front.
The recursive function for positive integers then becomes very simple: if it's zero, return empty string. For anything else, call itself with n/10, tack the n%10 to the right side of the result, and return that.
Here is also an alternative solution, without a private method:
public static String intToString( int n ) {
if ( n == 0 ) {
return "0";
} else if ( n < 0 ) {
return "-" + intToString( -n );
} else if ( n < 10 ) {
return "" + (n%10);
} else {
return intToString(n/10) + (n%10);
}
}
I actually consider this to be a slightly less efficient solution, because we do two more checks on each level. The check for negative will only be true once, at the top level. The check for zero will only be true if the function is called with zero in the first place. The check for single digit numbers is the current recursion end (because we can't stop the recursion at zero, otherwise we'll always get an extra "0" at the beginning).

Evaluating postfix expression using recursion

I need an algorithm for evaluating postfix expression using recursion. In this postfix expression an operand can be of more than one digit. A space is used to distinguish between two operands. So an expression '45 68 +' is valid.
I thought of evaluating it in reverse direction but I think that should not be correct.
Can someone help me with just the algorithm.
Thanks in advance.
Doesn't strike me as a recursive-friendly problem. But I'm sure it could be done that way.
Two approaches occur to me:
Option #1: Make functional recursion calls and returns match the stack push and pop operations described on the Wiki.
Down side to this approach is that you'll quickly find that the returned data from the function can be fairly complex. It'll probably be an operator. Maybe with an optional operand (IE: number). You'll be returning structures/objects that maybe should have operations (methods) on them.
Option #2: Each recursive call processes the next character of the input stream.
I think this approach would pass in as parameters the stack and maybe an "accumulator" for the current number -- to accumulate digits into a number before pushing it on the stack. There would be one massive tail recursion numeric result returned.
This approach is really just rewriting a loop as recursion.
Either way, figuring it out yourself should be challenging and educational!
Following is a sort of pseudo code which will work for postfix expressions with +/- . I think you can further extend the idea. If you still face difficulty then mail me to 2shanks.p#gmail.com as I am not regular on this site.
void recursivePostfix(char* expr)
{
if(!expr) return;
bool flag=true;
static double result=0;
double v1=result, v2=0, dec=0;
char oper='0';
int i=0, state=1;
do
{
if('0' != oper)
{
switch(oper)
{
case '+': result=v1+v2; break;
case '-': result=v1-v2; break;
case '*': result=v1*v2; break;
case '/': result=v1/v2; break;
}
oper = '0';
v1 = result;
v2 = 0;
recursivePostfix(expr+i);
}
if(SPACE_CHAR == *(expr+i) && state++)
continue;
switch(state)
{
case 1:
v1 = v1*10 + (expr[i]-'0'); break;
case 2:
v2 = v2*10 + (expr[i]-'0'); break;
case 3:
oper = *(expr+i);
}
}while(0 != *(expr+i++));
cout << result;
}
I just code this for an interview, so here is my solution using Python:
def recursive_postfix(s):
s = s.split(' ')
if len(s) == 1:
return s[0]
res = None
for i in range(len(s)):
if s[i] in ['+', '-', '*', '/']:
res = eval(f'{s[i-2]}{s[i]}{s[i-1]}')
break
s = s[0:i-2] + [str(res)] + s[i+1:]
return recursive_postfix(' '.join(s))
assert recursive_postfix('2 2 + 1 *') == '4' # (2 + 2) * 1
assert recursive_postfix('3 4 2 + * 5 *') == '90' # 3 * (4 + 2) * 5
assert recursive_postfix('7 2 2 * -') == '3' # 7 - (2 * 2)

Categories