【问题标题】:Finding common letters between 2 strings in Python在 Python 中查找 2 个字符串之间的常用字母
【发布时间】:2014-11-16 17:08:56
【问题描述】:

对于家庭作业,我必须获取 2 个用户输入的字符串,并找出有多少字母是共同的(在两个字符串的相同位置),以及找到共同的字母。例如对于两个字符串 ' cat' 和 'rat',有 2 个常见的字母位置(在这种情况下是位置 2 和 3),常见的字母也是 2,因为 'a' 找到了一个,'t' 也找到了一次..

所以我做了一个程序,它运行良好,但后来我的老师用更多的例子更新了作业,特别是重复字母的例子,我的程序不适合那个..例如,字符串 'ahahaha' 和'huhu' - 相同位置有 0 个常用字母,但它们之间有 3 个常用字母(因为字符串 2 中的 'h' 在字符串 1 中出现了 3 次..)

我的整个问题是我不知道如何计算“h”是否在第一个字符串中出现多次,以及我不知道如何不检查 huhu 中的第二个“h”,因为它应该只计算唯一的字母,所以总的常见字母数应该是 2..

这是我当前的代码:

S1 = input("Enter a string: ")
S2 = input("Enter a string: ")
i = 0
big_string = 0
short_string = 0
same_letter = 0
common_letters = 0

if len(S1) > len(S2):
    big_string = len(S1)
    short_string = len(S2)
elif len(S1) < len(S2):
    big_string = len(S2)
    short_string = len(S1)
elif len(S1) == len(S2):
    big_string = short_string = len(S1)

while i < short_string:
    if (S1[i] == S2[i]) and (S1[i] in S2):
        same_letter += 1
        common_letters += 1
    elif (S1[i] == S2[i]):
        same_letter += 1
    elif (S1[i] in S2):
        common_letters += 1
    i += 1

print("Number of positions with the same letter: ", same_letter)
print("Number of letters from S1 that are also in S2: ", common_letters)

所以这段代码适用于没有常用字母的字符串,但是当我尝试将它与“ahahaha”和“huhu”一起使用时,我得到 0 个常用位置(这是有道理的)和 2 个常用字母(当它应该是 3 时)。 . 我想如果我尝试添加以下内容可能会起作用:

while x < short_string:
    if S1[i] in S2[x]:
        common_letters += 1
    else:
        pass
    x += 1

然而这也不起作用......

我不是要求直接的答案或一段代码来做这件事,因为我想自己做,但我只需要一些提示或想法如何做到这一点..

注意:我不能使用我们在课堂上没有学过的任何函数,在课堂上我们只做了基本的循环和字符串..

【问题讨论】:

  • 更简单的方法:创建两个数组,每个数组有 26 个条目 (a-z)。循环遍历两个字符串并将它们“库存”到两个数组中。例如“foobar”给你a(1), b(1), f(1), o(2), r(1)。然后你遍历两个数组,看看哪些字母都有非零计数。
  • 使用集合和set.intersection
  • 在覆盖循环的时候,有没有覆盖enumerate()?

标签: python string letters


【解决方案1】:

您需要像multidict 这样的数据结构。据我所知,标准库中最相似的数据结构是Counter from collections

对于简单的频率计数:

>>> from collections import Counter
>>> strings = ['cat', 'rat']
>>> counters = [Counter(s) for s in strings]
>>> sum((counters[0] & counters[1]).values())
2

带索引计数:

>>> counters = [Counter(zip(s, range(len(s)))) for s in strings]
>>> sum(counters[0] & counters[1].values())
2

对于您的示例ahahahahuhu,您应该分别得到20,因为我们得到了两个h,但位置错误。

由于不能使用高级构造,因此只需使用数组模拟counter

  • 创建 26 个元素的数组
  • 遍历字符串并更新每个字母的相关索引
  • 同时再次循环遍历数组并对各个索引的最小值求和。

【讨论】:

    【解决方案2】:

    一个较短的版本是这样的:

    def gen1(listItem):
        returnValue = []
        for character in listItem:
            if character not in returnValue and character != " ":
                returnValue.append(character)
        return returnValue
    
    st = "first string"
    r1 = gen1(st)
    st2 = "second string"
    r2 = gen1(st2)
    
    if len(st)> len(st2):
        print list(set(r1).intersection(r2))
    else:
        print list(set(r2).intersection(r1))
    

    注意: 这是一个相当老的帖子,但由于它有新的活动,我发布了我的版本。

    【讨论】:

      【解决方案3】:

      由于不能使用数组或列表,

      也许尝试将每个常见字符添加到 var_string 然后测试 如果 c 不在 var_string 中: 在增加公共计数器之前,您不会多次计算同一个字符。

      【讨论】:

        【解决方案4】:

        您只会得到“2”,因为您只会查看 ahahaha 中的 4 个字符(因为最短的字符串 huhu 只有 4 个字符长)。将您的 while 循环改为通过 big_string,然后将 (len(S2) &gt; i) and 添加到您的两个条件测试中;最后一个测试执行in,所以不会引起索引长度问题。

        注意:以上所有内容都隐含地假设 len(S1) >= len(S2);这应该很容易确保,使用条件和赋值,它会简化代码的其他部分。您可以将第一个块完全替换为:

        if (len(S2) > len(S1)): (S2, S1) = (S1, S2)
        big_string = len(S1)
        short_string = len(S2)
        

        【讨论】:

          【解决方案5】:

          我们可以通过在另一个循环中使用一个 for 循环来解决这个问题,如下所示

          int y=0;
          for(i=0;i<big_string ;i++)
             {
               for(j=0;j<d;j++)
                  {
                     if(s1[i]==s2[j])
                     {y++;}
                  }
          

          如果你输入 'ahahaha' 和 'huhu' 这个代码取 big 的第一个字符 字符串 'a' 当它进入第一个 foo 循环时。当它进入第二个for循环时 它需要小字符串'h'的第一个字母并比较它们,因为它们不是 等于 y 不递增。在下一步中,它出现在第二个 for 循环中,但是 停留在第一个 for 循环中,因此它考虑大字符串 'a' 的第一个字符和 将它与小字符串 'u' 的第二个字母进行比较,因为 'j' 甚至增加 在这种情况下,它们都不相等,y 保持为零。 Y 递增 以下情况:-

          1. 当它比较大字符串“h”的第二个字母和第一个字符串的小写字母时,y 增加一次,即 y=1;
          2. 当它比较大字符串 'h' 的第四个字母和第一个字符串 y 的小写字母时,再次递增,即 y=2;
          3. 当比较大字符串 'h' 的第六个字母和第一个字符串 y 的小写字母时,再次递增,即 y=3;

          最终输出是 3。我认为这就是我们想要的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-10-08
            • 1970-01-01
            • 2017-07-07
            • 1970-01-01
            • 1970-01-01
            • 2013-02-09
            • 1970-01-01
            • 2010-12-15
            相关资源
            最近更新 更多