Java recursion count - java

First of all this is not homework. Just me practicing.
I'm trying to recursively determine the number of times "hi" appears in the given string, but in every case it skips to the last else if statement and things the string is empty. Any ideas?
Basically,
if(string starts with "hi")
increment count by 1 and recurse with the string after the 2nd index to skip over the "hi" it just counted
else if(string does not start with "hi" and string is not empty)
recurse with the string after its 1st index to see if it starts with "hi" the next time around.
else if(string is empty)
Print("End of text reached")
return count;
public class Practice {
public int recur(String str, int counter){
int count=counter;
if(str.startsWith("hi")){
count++;
recur(str.substring(2),count);
}
else if((!str.isEmpty())&&(!str.startsWith("hi"))){
recur(str.substring(1),count);
}
else if(str.isEmpty()){
System.out.println("End of text reached");
return count;
}
return count;
}
public static void main(String args[]){
String str="xxhixhixx";
Practice p=new Practice();
System.out.println(p.recur(str, 0));
}
}

This is a good opportunity to practice debugging recursive functions calls -- actually quite difficult. Suggestions:
use strategically placed print-statements to ensure that the arguments are being changed correctly from one recursive invocation to the next
refactor the order of case-analysis in the if-statement to make it more clear. For example, 1) check if the string is empty (base case), 2) check if the string starts with "hi", 3) catch-all -- not empty and doesn't start with "hi"

As #Steve mentioned, you have to use the return value that recur returns.
See below for a modified version of your code, I also simplified your if/else statements:
public int recur(String str, int counter) {
if (str.startsWith("hi")) {
return recur(str.substring(2), counter+1);
} else if (!str.isEmpty()) {
return recur(str.substring(1), counter);
} else {
System.out.println("End of text reached");
return counter;
}
}
public static void main(String args[]) {
String str = "xxhixhixx";
Practice p = new Practice();
System.out.println(p.recur(str, 0));
}

You aren't using the value returned from recur.

public int countHi(String str) {
if (str.length() <= 1) {
return 0;
}
int count = 0;
if (str.substring(0, 2).equals("hi")) {
count = 1;
}
return count + countHi(str.substring(1)); //substring off
}
All this does is recursively count the number of the String "hi" inside a larger String. The rest of the implementations should be a piece of cake, happy Coding!

Your program printing 'End of text' is correct as finally as per the logic it will reach there, reason for count always coming as 0 is that in every iteration they change there own copy and finally when the termination condition is reached(String is empty) the result is popped out of the stack, hence final outcome that you receive is the pop of the first iteration where count was 0, so you have to return the value returned by recur at every step instead of returning count.

public static int recursive(String givenStr) {
int count =0 ;
Pattern pattern = Pattern.compile("hi");
Matcher match = pattern.matcher(givenStr);
while(match.find()){
System.out.println(match);
count++;
}
return count;
}
This Will return number of times "hi" has appeared into the String

Related

Checking for equality throughout each character of string

I'm trying to build a palindrome. I think I might be overthinking the solution with way too many conditional loops inside my if statement. I'm having trouble trying to update the while loop to check whether it has gone through and checked for equality throughout each character of the string, and to update it. Can someone point me in the right direction, and also how can I do a cleaner job with code?
public class Main {
public static void main(String[] args) {
Main main = new Main();
main.isPalindrome("saippuakivikauppias");
main.isPalindrome("Hello World");
main.isPalindrome("Was it a car or a cat I saw");
}
private boolean isPalindrome(String word) {
int first = word.charAt(0);
int last = word.charAt(word.length() - 1);
if(word.length() <= 1) {
return true;
} else if(word.trim().length() > 1) {
if(Character.isLetter(first) && Character.isLetter(last)) {
while(first == last) {
first++;
last--;
//if loop to check if the while loop as gone through the entire string?
//update?
}
} else {
return false;
}
}
return false;
}
}
You really overthought this one - you should think a bit more basic about your problem:
A palindrome is a string that is the same read backward and forward -> create a reverse of word and compare to word
public static boolean isPalindrome(String word){
StringBuilder reverse = new StringBuilder(word).reverse();
return word.equals(reverse.toString());
}
You could even do this - depending on your coding style - in one line.

Searching for a String in an Array and returning the position

Hi I'm a complete newbie on programming and I try to search for a certain String in an array. When it's found the method should return the index but if the String is not found it should return -1.
public int poitionOfWord(String testWord) {
for (int i = 0; i < wordArray.length; i++) {
if (wordArray[i].equals(testWord)) {
return i;
}
}
return -1;
}
would this method return always -1 or would it actually terminate when finding a word and would return i.
Your method is correct and it will return the index in case it finds a match else if it doesn't find the match, it will come out of loop and return -1.
Just to make code crisp and concise, you can use something like this,
public static String[] wordArray = new String[]{"a", "b"};
public static int poitionOfWord(String testWord) {
return Arrays.asList(wordArray).indexOf(testWord);
}
Then test it with some code,
public static void main(String args[]) {
System.out.println(poitionOfWord("a"));
System.out.println(poitionOfWord("z"));
}
This prints,
1
-1
In general, when your function reaches a return statement, it will terminate and return the given value.

5th string needed from combination

Suppose there is a string s=abcd
I want the 5th string consisting of a,b,c,d, which is adbc.
But I also get all the answers beyond it which I don't need.
So how can I stop this method after its 5th execution?
import java.util.Arrays;
import java.util.Scanner;
class Test{
long times;
int n=1;
public static void main(String[] args) {
Test tm=new Test();
Scanner in=new Scanner(System.in);
int t=Integer.parseInt(in.nextLine());
while(t!=0){
String s=in.nextLine();
char ch[]=s.toCharArray();
Arrays.sort(ch);
String sort=String.valueOf(ch);
String ans;
long n=Long.parseLong(in.nextLine());
tm.times=n;
tm.permu("",sort);
t--;
}
}
private void permu(String prefix,String str) {
int len=str.length();
if(len==0){
if(n==times){
System.out.println(prefix);
}
else{
n++;
}
}
else{
for(int i=0;i<len;i++){
permu(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, len));
}
}
}
}
Secondly is there any site where I can read about permutation, combination and probability for calculating and finding the permutation, combination and probability... For coding thing not for mathematical thing..i.e I know how to solve mathematically but I can't code it.. Unable to write logic for it.
You don't change n after running the check and printing a result in your recursion. That's why you print everything after adbc.
If you use this code when checking:
if (n == times) {
System.out.println(prefix);
n = -1;
} else {
if (n > -1)
n++;
}
then you only get n == times to be true once, and that's when the prefix is adbc.
Example test for the solution:
If you want to stop a method that has no return value (has void in its return type in the method signature), then calling return; will exit the method... But it isn't needed here.

Make a for loop method with if statements return the correct "return" without array?

I am doing some java exercises and I am trying to make a method that counts to 100 and prints the number each time the for loop "loops". The exception is that it will print "Fizz" when the number is divisible by 3 and "Buzz" when the number is divisible by 5.
Now, I have three return types in my method that is gonna return a String. However, the error says I do not return a value. I am aware that I have to make it return a String outside the for loop but I am having some trouble figuring out how I should get to return the value that I want. I am also aware that I could use arrays or even arrayList to fix this problem but I think its possible without that and I would like to try doing so. Any help would be very appreciated! Here is the code:
package etcOvaningar;
public class ovning1 {
public static String fizz ="Fizz!";
public static String buzz ="Buzz!";
public static String countDown(){
for (int number = 0; number < 100; number++){
if (number%3 == 0){
return fizz;
}
else if (number%5 == 0){
return buzz;
}
else
return String.valueOf(number);
}
//I need to insert a return here I suppose, but I want the correct return from the if and else //statements
}
public static void main(String[] args){
}
}
Don't "return" in the loop, but rather print. When you return, the method exits, and the loop loops no more. If you simply print the necessary text, the for loop will continue to loop until it reaches its natural end condition.
public static void countDown(){
for (int number = 0; number < 100; number++){
if (number % (3*5) == 0) {
System.out.println("fizzbuzz");
} else
if (number % 3 == 0){
System.out.println("fizz");
} else
if (number % 5 == 0){
System.out.println("buzz");
}
}
}
Note as per Martin Dinov, this method should be declared to return void, nothing.
Your code won't compile because method countdown needs return value below the for loop.
However whatever you return value you put below the for loop won't matter because your countdown method will always return "Fizz!"
This is another way to do what you want to do. Perhaps, more of what you really should be doing.
private static String fizz ="Fizz!";
private static String buzz ="Buzz!";
public static void main(String[] args){
for (int number = 0; number < 100; number++){
String word = checkNumber(number);
System.out.println(word);
}
}
private static String checkNumber(int number){
String value = "";
if (number%3 == 0){
value += fizz;
}
if (number%5 == 0){
value += buzz;
}
if (value.isEmpty()) {
value = String.valueOf(number);
}
return value;
}
Points to note:
Start your methods and fields as private and upgrade their visibility as you further develop your program and your needs change. This helps keep the code clean and the exposure to the minimum.
Try not to have print statements in methods (unless they are specifically designed for printing messages). They should take an input, process the input and return an output. Nothing more, nothing less.
Understand the difference between if / else if / else and if / if / if. The number 15 is divisible by both 3 and 5.

Keeping count in a recursive Java method

Here's what I'm trying to accomplish with this program: a recursive method that checks if the number of instances of a substring matches a specified amount of instances, returning a boolean.
Here's the issue I'm having with this particular recursive method: I'd like to be able to move the counter inside the recursive method body, however, I ran into the issue that the counter resets at each recursive call when it is in the method body. The only way I have been able to make it work is through the use of a static counter variable declared outside of the function body. Is there any other technique I can marshall in order to be able to situate the counter of the method in the method body so that this method may act as a "black box"?
Thanks for any advice or insights you can provide.
public class strCopies {
//count instances of part and whole equality
static int count = 0;
public static boolean copies(String whole, String part, int check)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(count == check)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check);
}
public static void main(String[] args)
{
System.out.println(copies("dogcatdog", "cat", 2));
}
}
You are almost there: you should change the meaning of the check variable to the remaining number of matches, rather than the original number requested. Then you can rewrite the method without keeping an additional count at all, as follows:
public static boolean copies(String whole, String part, int check)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(check == 0)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
check--;
}
return return copies(whole.substring(1), part, check);
}
You can pass the count as an argument to the recursive function, this way it will not be "reset" when the method is called.
public static boolean copies(String whole, String part, int check, int count)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(count == check)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
public int countRecursive(String whole, String part){
if(whole.length() < part.length()) return 0;
if(part.length()==0) return -1; // ints can't express "Infinity"
// maybe you want to return -1 only if whole is not null, and something else if it is.
int count = 0;
if(whole.substring(0, part.length()).equals(part))
count = 1;
return countRecursive(whole.substring(1), part) + count;
}
public boolean count(String whole, String part, int check){
return countRecursive(whole, part) == check;
}
Note that this does away with the counter at the expense of creating a whole bunch of strings for each state. (You replace a single int with the length of each string given.) But then again, if you want performance then you shouldn't be using recursion for something like this. A simple for loop would do much nicer.
You could add the counter to the method parameters as follows:
public class strCopies {
public static boolean copies(String whole, String pargs, int check){
return copies(whole, pargs, check, 0);
}
public static boolean copies(String whole, String part, int check, int count)
{
//check if current string length is valid
if(whole.length() < part.length()) {
//check if check parameter equals part instances
if(count == check) {
return true;
}
else {
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part)) {
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
public static void main(String[] args) {
System.out.println(copies("dogcatdog", "dog", 2));
}
}
The simple version:
Create a class that contain the counter.
Initialize it on your main.
Pass its reference to the function.
Another idea:
Create a singleton class with a static counter and your function X.
Inside its constructor add one to its counter and call function X.
Then instead of running your function like you did before, "create" that class, thus increasing the counter and calling the function.
The neat thing is you can inherit that class and redefine X to whatever you choose at a latter stage, so you get this general class that counts on each activation of a function.
Not sure what is your recursive method doing. However, to maintain a counter, you can pass it as an argument to your recursive method.
public boolean copies(String whole, String part, int check, int count) {
// your code here....
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
When you make first call to your copies method, you'll need to pass 0 to your count.

Categories