Implement my own recursive version of the indexOf method - java

So I'm trying to write recursive method indexOf which returns the starting index of the first occurrence of the second String inside the first String (or -1 if not found).For example, the call of indexOf (“Barack Obama”, “bam”) would return 8. Also I know that String class has method IndexOf, but I don't want to use it.
So far this is my code:
public class MyClass {
public static void main(String[] args) {
}
public static int indexOf(String s, String t) {
return abc(s, t, 0);
}
public static int abc(String a, String b, int c) {
if ((a.length() - c) < b.length()) {
return -1;
} else if (b.equals(a.substring(c, c + 3))) {
return c;
} else {
}
}
}

It depends how much of the library you want to use.
One option is:
int indexOf(String container, String text, int index) {
//Too short container
if (container.length() < text.length()) return -1;
//found
else if (container.startsWith(text)) return index;
//keep searching
else return indexOf(container.substring(1), text, index+1);
}
indexOf("banana", "nana", 0) == 2;
If you don't want to use .startsWith, then you need to implement your own version. A very good exercise would be to try and do this without ever using the .substring method, which is terrible (as it creates a copy of the string, O(n) space/time performance), and which is not needed for this task (use .charAt)
You can also split the official method indexOf from its recursive call that includes the index for more clarity).
You should think carefully about edge cases too :)

Related

How do I make this function return the value I'm looking for?

I made a function that's meant to count the number of specific chars in a function recursively.
public static int countCharInString(String s, char c)
{
return countCharInString(s, c, 0);
}
public static int countCharInString(String s, char c, int index)
{
if(index==s.length())
{
return 0;
}
if(s.charAt(index) == c)
{
return 1 + countCharInString(s, c, index+1);
}
if(s.charAt(index)!=c)
{
return countCharInString(s, c, index+1);
}
}
How can I put a return statement at the end of the function that'll return the whole number I "counted" inside the function?
You don't need an extra return statement at the end of the method, the error you're getting is because the compiler isn't convinced that you've got all cases covered.
The easiest fix for this is to simply replace your second comparison against c with else. Either the character is equal to c or it isn't, you don't need a separate check.
e.g.
public static int countCharInString(String s, char c, int index) {
if (index == s.length()) {
return 0;
}
if (s.charAt(index) == c) {
return 1 + countCharInString(s, c, index + 1);
} else {
return countCharInString(s, c, index + 1);
}
}
I would use a for Loop, If the recursion is needed, Check If
Index+1 > s.length()
If this is the Case the recursion should return
You need to have a parameter to keep track of your running total. Add a parameter to your function which you'll increment each time you find the character. Then return that number instead of returning 0
Using recursion here does not make sense to me. The number of characters in a string is going to be `s.length()'.
However, since this is your requirement - I believe you want the count of some character - I recognized this as a classic 're-invent' the wheel program. While I dislike these, the important thing here is to understand what is happening.
Firstly, you don't need a variable for index... because you always set it to 0. So just use 0.
Secondly, let's use substring so we don't have to convert to chars and deal with character/String comparisons etc.
public static int countCharInString(String s, String c) {
// This will only happen when the string is empty to begin with, our we're done with recursion. Since we add this to another number in recursion - it works for our purpose
if (s.length() == 0) {
return 0;
}
// If we have a match, increment add add to our recursive sum
if ((s.substring(0, 1).equals(c))) {
return 1 + countCharInString(s.substring(1), c);
}
// do the final return and invoke recursion
return countCharInString(s.substring(1), c);
}

return statement does not ending method java

public class Interpolation_search {
public static void main(String...s) {
int rr[]= {1,2,3,4,9,10,15,80};
System.out.println(search(rr,0,7,3));
}
static int search(int ar[], int lo, int hi,int X) {
if(lo<hi&&ar[lo]!=ar[hi]) {
int mid=lo + ((hi-lo)/(ar[hi]-ar[lo]))*(X-ar[lo]);
if(X==ar[mid])
return 1; //l1
else if(X>ar[mid])
search(ar,mid+1,hi,X);
else search(ar,lo,mid-1,X);
}
return 0; //l2
}
}
return is executing twice first at l1 and second at l2.
It seems that you have difficulties understanding recursion.
Your method search() is supposed to return an int result. And the method itself calls itself (using different arguments) repeatedly. Thing is: you are all ignoring these recursive calls.
In other words: the real answer is for you to step back and understand what recursion is meant to be, and how to properly use it. As a starter, you could try to change
search(ar,mid+1,hi,X);
to
return search(ar,mid+1,hi,X);

Java: Recursively search an array for an integer given an array, integer, and array length

I'm trying to write a recursive method that accepts an int array, number of elements in the array, and an integer, and returns whether the integer is present as an element in the array.I just can't figure out why I this isn't working for all my test cases. Any help would be much appreciated!
public static boolean search(int[] findIn, int target, int len){
if(len == 0){
return false;
}else if(findIn[len-1] == target){
return true;
}else{
return search(findIn, target, len-1);
}
}
Yes I realize there are better ways other than recursion to do this, but it is required that I do it this way.
My main method looks like this: I'm just hard-coding it for the time being:
int[] arr = {1};
System.out.println(search(arr,1,1));
Testcases:
I am almost certain, that your method parameters are in the wrong order:
Your results hint that you switched the 2nd and 3rd parameter!
Maybe this
static boolean search(int[] findIn, int target, int len)
should actually be
static boolean search(int[] findIn, int len, int target)
From what I can see, that code should work fine so I suspect your problem lies in your test cases rather than here.
One thing I will mention is that use of if-return-else constructs tend to complicate your code unnecessarily.
It's usually better to avoid that with something like:
public static boolean search(
int[] findIn, int target, int len)
{
if (len == 0)
return false;
if (findIn[len-1] == target)
return true;
return search(findIn, target, len-1);
}
I find that a lot easier to follow at a glance than trying to track what if clause I happen to be in at any given moment.
In any case, both it and your version perform fine, at least for small test cases. The first time you pass in a ten-million-element array is probably when you'll discover it's not the best poster child for recursion.
I tried something like this and it is working..
I am using a static instance variable to find the position of number in array.
In stead of returning the position of number you can modify to return a boolean
public class RecSearch {
static int pos=0;
public static void main(String[] args) {
int a[] = {1};
System.out.println(recSearch(a, 0));
System.out.println(recSearch(a, 1));
}
public static int recursiveSearch(int[] arr, int numtoSearch) {
if (pos>=arr.length) {
pos=0;
return -1;
}
if (arr[pos]==numtoSearch)
return (pos+1);
else {
pos++;
return recursiveSearch(arr, numtoSearch);
}
}
}
public class Solution {
public static boolean checkNumber(int input[], int x) {
return check(input,x,0);
}
public static boolean check(int input[],int x,int start){
if(start==input.length)
return false;
if(input[start]==x)
return true;
return check(input,x,start+1);
}
}

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.

Java recursion count

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

Categories