关于python:评估字符串是否是另一个字符串

Evaluating whether a string is a subanagram of another

我想创建一个带有两个参数的函数(x,y),x和y是一个字符串,如果x是y的子变位词,则返回true。例如:"red"是"red a"的子变位词,但"reda"不是"red"的子变位词。

到目前为止,我得到了:我已经将x,y转换成列表,然后对它们进行排序。这样我就可以比较每个字符串的字母。

1
2
3
4
5
6
7
8
9
10
def sub_anagram(str1, str2):
    s1 = list(str1)
    s2 = list(str2)
    s1.sort()
    s2.sort()
    for letters in s2:
        if letters in s1:
            return True
        else:
            return False

我困惑的是:我想将字符串y与x进行比较,如果y包含x中的所有字符,则返回true,否则返回false


您可以使用collections.Counter

1
2
3
4
5
from collections import Counter
def subanagram(str1, str2):
    str1_counter, str2_counter = Counter(str1), Counter(str2)
    return all(str1_counter[char] <= str2_counter[char]
                 for char in str1_counter)

在上面的代码中,str1_counter基本上是一个字典,其中str1中出现的字符及其频率是键、值。同样适用于str2_counter

然后,代码检查对于str1中的所有字符,该字符在str2中出现的次数至少与在str1中出现的次数相同。

编辑:如果子管理被定义为严格小于原始的,例如,您希望subanagram("red","red")False,那么首先比较两个计数器是否相等。

1
2
3
4
5
6
7
from collections import Counter
def subanagram(str1, str2):
    str1_counter, str2_counter = Counter(str1), Counter(str2)
    if str1_counter == str2_counter:
        return False
    return all(str1_counter[char] <= str2_counter[char]
                 for char in str1_counter)

如果我出于某种原因不使用Counter,这将是符合以下原则的:

1
2
3
4
5
6
7
8
9
10
11
def subanagram(str1, str2):
    if len(str1) == len(str2):
        return False  #Ensures strict subanagram

    s2 = list(str2)
    try:
        for char in str1:
            s2.remove(char)
    except ValueError:
        return False
    return True

但如您所见,它比使用Counter更长、更少声明性和更低的效率。


我认为你不能只检查x中的每个字符是否存在于y中,因为这不能解释x中重复的字符。换句话说,"reeeed"不是"reda"的子变位词。

这是一种方法:

  • 复制Y
  • 对于x中的每个字符,如果该字符出现在y-copy中,请将其从y-copy中删除。如果它不存在,返回false。
  • 如果到达循环的末尾,而y-copy为空,则返回false。(x是变位词,但不是子变位词。)
  • 否则返回true。