python使用递归计算字符串中的字符数

Python count characters in a string using recursion

我在这里坐了3个小时,想知道怎么做。我必须做一个名为countletterstring(char,str)和countletterfile(char,textfile)的原始函数。我需要使用递归来查找给定字符在字符串中出现的次数,并使用for循环来确定它在文本文件中出现的次数。我真的对如何开始感到困惑。

1
2
3
4
5
def countLetterString(char, str):
    if str == 0:
       return 0
    else:
    .... countLetterString(...)

我不明白它是怎么工作的:/

编辑:我感谢迄今为止的所有帮助:)这真的有助于我理解这个概念。到目前为止,我的代码是这样的。

def countletterstring(字符,字符串):

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

所有这些都是计算字符串中有多少个字符,但我似乎不知道如何拆分字符串,然后查看字符是否是字符拆分。


第一步是将此问题分解为多个部分:

1。如何确定字符是否在字符串中?

如果是递归地执行此操作,则需要检查字符串的第一个字符。

2。如何比较两个字符?

python有一个==运算符,用于确定两个事物是否等价。

三。知道字符串的第一个字符是否匹配后,我该怎么做?

您需要继续到字符串的其余部分,但仍需要以某种方式维护到目前为止看到的字符数。对于for循环,这通常非常容易,因为您可以在其外部声明一个变量,但是递归地,您必须将程序的状态传递给每个新的函数调用。

下面是一个递归计算字符串长度的示例:

1
2
3
4
5
6
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:] )

从这个例子中,看看您是否可以完成您的问题。您的将有一个单独的额外步骤。

4。我什么时候停止递归?

在处理递归时,这总是一个问题,什么时候我需要停止调用自己。看看你能不能弄清楚这个。

编辑:

not s将测试s是否为空,因为在python中,空字符串""的计算结果为Falsenot False == True


首先,您不应该使用str作为变量名,因为它会屏蔽内置str类型。用像stext之类的东西代替。

if str == 0:行不会像您期望的那样做,检查字符串是否为空的正确方法是使用if not str:if len(str) == 0:(首选第一种方法)。有关详细信息,请参阅此答案。

现在你已经知道了递归的基本情况,那么"步骤"是什么。您将要返回1 + countLetterString(...)0 + countLetterString(...),您在其中调用countLetterString(),少一个字符。如果删除的字符与char0匹配,则使用1。例如,可以检查s中的第一个字符是否与使用s[0] == charchar匹配。

要删除字符串中的单个字符,可以使用切片,因此对于字符串s,可以获取除第一个使用s[1:]之外的所有字符,或者除最后一个使用s[:-1]之外的所有字符。希望这足以让你开始!


关于递归的推理需要将问题分解为"常规"和"特殊"情况。这里的特例是什么?如果字符串是空的,那么char肯定不在字符串中。在这种情况下返回0。

还有其他特殊情况吗?不是真的!如果字符串不是空的,可以将其分解为第一个字符(the_string[0])和其余所有字符(the_string[1:])。然后,您可以递归地计算其余部分中出现的字符数,如果第一个字符等于您要查找的char,则添加1。

我认为这是一个任务,所以我不会为您编写代码。这并不难。注意你的if str == 0:不起作用:这是在测试str是否是整数0if len(str) == 0:是一种可行的方法,而if str =="":是另一种。有较短的方法,但在这一点上,这些可能是最清楚的。


你必须先决定一个基本情况。递归展开并返回的点。

在这种情况下,基本情况是字符串中没有(进一步的)特定字符的实例,比如X。(if string.find(X) == -1: return count和函数不再对自身进行调用,并返回找到的实例数,同时信任其以前的调用方信息。

递归是指从内部调用自身的函数,因此创建一个调用堆栈(至少在python中),每个调用都是单独的,并且具有指定的用途,不知道调用之前发生了什么,除非提供了这样的调用,否则它会向该调用添加自己的结果并返回(严格来说不是这样)。这些信息必须由它的调用程序、父对象提供,或者可以使用全局变量来完成,这是不可取的。

因此,在本例中,信息是父函数在字符串的第一个分数中找到特定字符的实例数。我们所做的初始函数调用也需要提供这些信息,因为我们是所有函数调用的根,并且不知道(因为我们没有遍历字符串)有多少个X,所以我们可以安全地告诉初始调用,因为我没有遍历字符串,也没有找到任何或零/0if string.find(X) == -1: return count。0]因此,这是一根完整的绳子,你能不能踩下它的其余部分,然后用find计算出里面有多少个X。为了方便起见,这个0可能是函数的默认参数,或者每次调用时都必须提供0

函数什么时候调用另一个函数?

递归将任务分解为最细化的级别(严格地说,可能),剩下的部分留给(grand)子级(ren)。此任务的最细微的分解是find,它使用X的单个实例,并将字符串的其余部分从发生该任务的点(+ 1)传递到下一个调用,然后将1添加到其父函数提供该任务的count中。

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

通过迭代/循环对文件中的X进行计数。

它涉及到open生成文件(TextFILE),然后text = read(TextFile)生成文件,text生成str。然后循环遍历每个字符(for char in text:),记住粒度,每次char(等于)== Xcount增加+=1。在运行循环之前,请指定您从未通过过string,因此您的count用于数字X(在text)的count= 0。(听起来很熟悉?)

return count


首先,我建议您不要使用char或str。str是一个内置的函数/类型,虽然我不认为char会给您带来任何问题,但它在许多其他语言中是一个保留字。其次,您可以使用count实现相同的功能,如:

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

它将给出给定字符串中出现i的次数,在本例中为3。

如果您纯粹是为了猜测而需要这样做,那么递归中要记住的事情就是携带一些条件或计数器,在这些条件或计数器上每次调用,并在代码中放置某种条件来改变它。例如:

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

请记住,这是一个很快的例子,但是正如您在每次调用中看到的,我打印当前值,然后函数在递减计数的同时再次调用自身。一旦计数不再大于0,函数将结束。

知道了这一点,您将想要跟踪您的计数、您正在比较的字符串中的索引、您正在搜索的字符以及您的示例中的字符串本身。如果不为您编写代码,我认为这至少会给您一个开始。