基本Anagram VS更高级的一个

时间:2016-09-30 18:08:48

标签: python python-2.7 python-3.x

我目前正在通过" List"单位和其中一个练习我们需要创建一个字谜(对于那些不知道的人;如果你可以重新排列一个字母来拼写另一个,那么两个单词就是字谜)。

想到的更简单的解决方案是:

def is_anagram(a, b):
    return sorted(a) == sorted(b)

print is_anagram('god', 'dog')

它有效,但它并不能让我满意。如果我们处于这种情况,例如:

def is_anagram(a, b):
    return sorted(a) == sorted(b)

print is_anagram('god', 'dyog') #extra letter 'd' in second argument
>>> False

返回为假,但我们应该能够从'god'构建单词'dyog'。也许这个游戏/问题并不被称为字谜,但无论如何我一直试图解决这个问题。

从技术上讲,我的解决方案是:
1-迭代b的每个元素。
2-正如我所做的那样,我检查一下这个元素是否存在 3-如果他们都这样做;然后我们可以创建一个b。
4-否则,我们不能。

我似乎无法让它发挥作用。 为了记录,我不知道如何使用lambda

有些测试:

print is_anagram('god', 'ddog') #should return True
print is_anagram('god', '9d8s0og') #should return True
print is_anagram('god', '_@10d_o g') #should return True

谢谢:)

5 个答案:

答案 0 :(得分:1)

如果您需要检查是否可以从a创建b字词,则可以执行此操作

def is_anagram(a,b):
    b_list = list(b)
    for i_a in a:
        if i_a in b_list:
            b_list.remove(i_a)
        else:
            return False
    return True

<强> UPDATE(说明)

b_list = list(b)生成liststr个对象(字符)。

>>> b = 'asdfqwer'
>>> b_list = list(b)
>>> b_list
['a', 's', 'd', 'f', 'q', 'w', 'e', 'r']

答案中基本上发生了什么:我们检查a中列出的b_list中的每个字符,当发生事件时,我们会从b_list删除该字符(我们这样做是为了消除这种可能性)使用输入True'good')返回'god'。因此,如果在a的其余部分中没有出现b_list的其他字符,则它不是高级字谜。

答案 1 :(得分:1)

由于其他答案没有,在撰写本文时,支持撤销订单:

为方便起见,

包含type hints,因为为什么不呢?

# Just strip hints out if you're in Python < 3.5.
def is_anagram(a: str, b: str) -> bool:
    long, short = (a, b) if len(a) > len(b) else (b, a)
    cut = [x for x in long if x in short]
    return sorted(cut) == sorted(short)

如果将来学习使用lambda,则等效于:

# Again, strip hints out if you're in Python < 3.5.
def is_anagram(a: str, b: str) -> bool:
    long, short = (a, b) if len(a) > len(b) else (b, a)
    # Parentheses around lambda are not necessary, but may help readability
    cut = filter((lambda x: x in short), long)
    return sorted(cut) == sorted(short)

答案 2 :(得分:0)

试试:

def is_anagram(a, b):
    word = [filter(lambda x: x in a, sub) for sub in b]
    return ''.join(word)[0:len(a)]

示例:

>>> is_anagram('some','somexcv')
'some'

注意:此代码会返回common word(如果有)或''。 (它没有像OP那样返回True/False - 意识到之后,但无论如何这个代码可以很容易地改变以适应True/False类型的结果 - 我现在不会修复它这个帖子里有很好的答案已经做了:))

  

简要说明:

此代码对filter字中存在的sub字上的每个字母b)都采用(a)。最后返回必须与([0:len(a)])具有相同长度的单词。 len的最后一部分需要这样的情况: is_anagram('some','somenothing')

答案 3 :(得分:0)

def is_anagram(a, b):
    test = sorted(a) == sorted(b)
    testset = b in a
    testset1 = a in b
    if testset == True:
        return True
    if testset1 == True:
        return True
    else:
        return False

不比其他解决方案好。但如果你喜欢详细的代码,那么这就是我的。

答案 4 :(得分:0)

我认为所有这些分类都是红鲱鱼;这些字母应该被计算在内。

def is_anagram(a, b):
    return all(a.count(c) <= b.count(c) for c in set(a))

如果你想要效率,你可以构建一个字典来计算b中的所有字母,并减少a中每个字母的这些计数。如果任何计数低于0,则b中没有足够的字符实例来创建a。这是O(a + b)算法。

from collections import defaultdict

def is_anagram(a, b):
    b_dict = defaultdict(int)

    for char in b:
        b_dict[char] += 1

    for char in a:
        b_dict[char] -= 1
        if b_dict[char] < 0:
            return False

    return True

b进行迭代是不可避免的,因为你需要计算那里的所有字母。一旦找不到a中的字符,这将立即退出,因此我认为您不能过多地改进此算法。