user123456789101112
user123456789101112

Reputation: 55

Count occurrences of a given character in a string using recursion

I have to make a function called countLetterString(char, str) where I need to use recursion to find the amount of times the given character appears in the string.

My code so far looks like this.

def countLetterString(char, str):
    if not str:
        return 0
    else:
        return 1 + countLetterString(char, str[1:])

All this does is count how many characters are in the string but I can't seem to figure out how to split the string then see whether the character is the character split.

Upvotes: 1

Views: 27972

Answers (8)

Rishabh Barman
Rishabh Barman

Reputation: 569

The below function signature accepts 1 more parameter - count.

(P.S : I was presented this question where the function signature was pre-defined; just had to complete the logic.)

Hereby, the code :

def count_occurrences(s, substr, count=0):
    ''' s - indicates the string,
        output : Returns the count of occurrences of substr found in s
    '''
    
    len_s = len(s)
    len_substr = len(substr)

    if len_s == 0:
        return count

    if len_s < len_substr:
        return count
    
    if substr == s[0:len_substr]:
        count += 1

    count = count_occurrences(s[1:], substr, count)       ## RECURSIVE CALL

    return count

output behavior :

count_occurences("hishiihisha", "hi", 0) => 3

count_occurences("xxAbx", "xx") => 1 (not mandatory to pass the count , since it's a positional arg.)

Upvotes: 0

Yash Gupta
Yash Gupta

Reputation: 1

With an extra parameter, the same function can be implemented. Woking function code:

def countLetterString(char, str, count = 0):
    if len(str) == 0:
        return count
    if str[-1] == char:
        return countLetterString(char, str[0:-1], count+1)
    else:
        return countLetterString(char, str[0:-1], count)

Upvotes: 0

Yash Gupta
Yash Gupta

Reputation: 1

#This function will print the count using recursion.
def countrec(s, c, cnt = 0):
    if len(s) == 0:
        print(cnt)
        return 0
    if s[-1] == c:
        countrec(s[0:-1], c, cnt+1)
    else:
        countrec(s[0:-1], c, cnt)

#Function call
countrec('foobar', 'o')

Upvotes: 0

Bleeding Fingers
Bleeding Fingers

Reputation: 7129

You have to decide a base case first. The point where the recursion unwinds and returns.

In this case the the base case would be the point where there are no (further) instances of a particular character, say X, in the string. (if string.find(X) == -1: return count) and the function makes no further calls to itself and returns with the number of instances it found, while trusting its previous caller information.

Recursion means a function calling itself from within, therefore creating a stack(at least in Python) of calls and every call is an individual and has a specified purpose with no knowledge whatsoever of what happened before it was called, unless provided, to which it adds its own result and returns(not strictly speaking). And this information has to be supplied by its invoker, its parent, or can be done using global variables which is not advisable.

So in this case that information is how many instances of that particular character were found by the parent function in the first fraction of the string. The initial function call, made by us, also needs to be supplied that information, since we are the root of all function calls and have no idea(as we haven't treaded the string) of how many Xs are there we can safely tell the initial call that since I haven't gone through the string and haven't found any or zero/0 X therefore here's the string entire string and could you please tread the rest of it and find out how many X are in there. This 0 as a convenience could be the default argument of the function, or you have to supply the 0 every time you make the call.

When will the function call another function?

Recursion is breaking down the task into the most granular level(strictly speaking, maybe) and leave the rest to the (grand)child(ren). The most granular break down of this task would be finding a single instance of X and passing the rest of the string from the point, exclusive(point + 1) at which it occurred to the next call, and adding 1 to the count which its parent function supplied it with.

if not string.find(X) == -1:
    string = string[string.find(X) + 1:]
    return countLetterString(char, string, count = count + 1)`

Counting X in file through iteration/loop.

It would involve opening the file(TextFILE), then text = read(TextFile)ing it, text is a string. Then looping over each character (for char in text:) , remember granularity, and each time char (equals) == X, increment count by +=1. Before you run the loop specify that you never went through the string and therefore your count for the number X (in text) was = 0. (Sounds familiar?)

return count.

Upvotes: 0

lgraham076
lgraham076

Reputation: 81

First of all you I would suggest not using char or str. Str is a built function/type and while I don't believe char would give you any problems, it's a reserved word in many other languages. Second you can achieve the same functionality using count, as in :

letterstring="This is a string!"
letterstring.count("i")

which would give you the number of occurrences of i in the given string, in this case 3.

If you need to do it purely for speculation, the thing to remember with recursion is carrying some condition or counter over which each call and placing some kind of conditional within the code that will change it. For example:

def  countToZero(count):
   print(str(count))
   if count > 0:
      countToZero(count-1)

Keep it mind this is a very quick example, but as you can see on each call I print the current value and then the function calls itself again while decrementing the count. Once the count is no longer greater than 0 the function will end.

Knowing this you will want to keep track of you count, the index you are comparing in the string, the character you are searching for, and the string itself given your example. Without doing the code for you, I think that should at least give you a start.

Upvotes: 0

Hunter McMillen
Hunter McMillen

Reputation: 61510

The first step is to break this problem into pieces:

1. How do I determine if a character is in a string?

If you are doing this recursively you need to check if the first character of the string.

2. How do I compare two characters?

Python has a == operator that determines whether or not two things are equivalent

3. What do I do after I know whether or not the first character of the string matches or not?

You need to move on to the remainder of the string, yet somehow maintain a count of the characters you have seen so far. This is normally very easy with a for-loop because you can just declare a variable outside of it, but recursively you have to pass the state of the program to each new function call.

Here is an example where I compute the length of a string recursively:

def length(s): 
   if not s:  # test if there are no more characters in the string
      return 0
   else:  # maintain a count by adding 1 each time you return
          # get all but the first character using a slice
      return 1 + length( s[1:] )

from this example, see if you can complete your problem. Yours will have a single additional step.

4. When do I stop recursing?

This is always a question when dealing with recursion, when do I need to stop recalling myself. See if you can figure this one out.

EDIT:

not s will test if s is empty, because in Python the empty string "" evaluates to False; and not False == True

Upvotes: 3

Andrew Clark
Andrew Clark

Reputation: 208505

First of all, you shouldn't use str as a variable name as it will mask the built-in str type. Use something like s or text instead.

The if str == 0: line will not do what you expect, the correct way to check if a string is empty is with if not str: or if len(str) == 0: (the first method is preferred). See this answer for more info.

So now you have the base case of the recursion figured out, so what is the "step". You will either want to return 1 + countLetterString(...) or 0 + countLetterString(...) where you are calling countLetterString() with one less character. You will use the 1 if the character you remove matches char, or 0 otherwise. For example you could check to see if the first character from s matches char using s[0] == char.

To remove a single character in the string you can use slicing, so for the string s you can get all characters but the first using s[1:], or all characters but the last using s[:-1]. Hope that is enough to get you started!

Upvotes: 2

Tim Peters
Tim Peters

Reputation: 70602

Reasoning about recursion requires breaking the problem into "regular" and "special" cases. What are the special cases here? Well, if the string is empty, then char certainly isn't in the string. Return 0 in that case.

Are there other special cases? Not really! If the string isn't empty, you can break it into its first character (the_string[0]) and all the rest (the_string[1:]). Then you can recursively count the number of character occurrences in the rest, and add 1 if the first character equals the char you're looking for.

I assume this is an assignment, so I won't write the code for you. It's not hard. Note that your if str == 0: won't work: that's testing whether str is the integer 0. if len(str) == 0: is a way that will work, and if str == "": is another. There are shorter ways, but at this point those are probably clearest.

Upvotes: 1

Related Questions