快速和pythonic方式来确定anagram是否是回文?

时间:2014-03-26 09:35:23

标签: python

给定一个字符串,我们如何检查它的任何字谜是否可以作为回文?

例如,让我们考虑字符串“AAC”。它的字谜是“ACA”,它是一个回文。如果我们可以从给定字符串的任何anagram形成回文,我们必须编写一个接受字符串并输出true的方法。否则输出错误。

这是我目前的解决方案:

from collections import defaultdict

def check(s):
    newdict = defaultdict(int)
    for e in s:
        newdict[e] += 1
    times = 0
    for e in newdict.values():
        if times == 2:
            return False
        if e == 1:
            times += 1
    return True

使用python库的任何更短的解决方案?

4 个答案:

答案 0 :(得分:5)

这是使用标准库的更短解决方案,使用更正的算法(所有字符数必须是偶数,除了最多一个):

from collections import Counter
def check(s):
    return sum(1 for count in Counter(s).itervalues() if count % 2 == 1) <= 1

这很简短,但是很慢&#34;,因为程序会经历所有奇数计数而不是在找到两个计数后立即停止。一个尽快停止的更快的解决方案是:

def check(s):
    odd_counts = (count for count in Counter(s).itervalues() if count % 2 == 1)
    try:
        next(odd_counts)  # Fails if there is no odd count
        next(odd_counts)  # Fails if there is one odd count
    except StopIteration:
        return True
    else:
        return False

答案 1 :(得分:2)

这可能更适合代码打高尔夫球,但是它非常简单。

观察到回文需要一组平衡的侧面,因此每种类型通常需要偶数个输入。但是,可以在中间提供单个奇数项,因此您基本上可以将其提升到最多一组奇数字符。这可以通过单个列表理解来完成

>>> from collections import Counter
>>> def is_palindrome(letters):
...     return len([v for v in Counter(letters).values() if v % 2]) <= 1
... 
>>> is_palindrome('level')
True
>>> is_palindrome('levels')
False
>>> is_palindrome('levelss')
True

哦等等,其他人用解决方案打败了,但这就是我得到的。

答案 2 :(得分:0)

不使用Counter:

>>> def isit(s):
...     ls = [ x % 2 for x in [s.count(x) for x in set(s)]]
...     return [False, True][all(ls) or ls.count(1) == 1]
...
>>> isit('abc')
False
>>> isit('abb')
True
>>> isit('abbd')
False
>>> isit('abbdd')
True
>>> isit('abbdda')
True
>>>

答案 3 :(得分:0)

即使它在算法上不是最好的,(如果你的字符串不是很长,这不是问题),我想提供一个更易读的解决方案。

from itertools import permutations

def has_palindrome(s):
    return any(c == c[::-1] for c in permutations(s,len(s)))