Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何检查序列是否可以转换为回文_Python_Sorting_Python 3.x_Palindrome - Fatal编程技术网

Python 如何检查序列是否可以转换为回文

Python 如何检查序列是否可以转换为回文,python,sorting,python-3.x,palindrome,Python,Sorting,Python 3.x,Palindrome,我必须找出列表是否可以是回文。我的程序的第一部分对列表进行排序 A = [0, 99, 97, 97, 99, 100, 100, 0] # sorted: B = [0, 0, 97, 97, 99, 99, 100, 100] 此列表可以是回文,因为它可以重新排序为: [0, 97, 99, 100, 100, 99, 97, 0] 我编写了以下代码,以在列表可以是回文时返回True i=0 counter = 0 while i<len(B): if i+1 <

我必须找出列表是否可以是回文。我的程序的第一部分对列表进行排序

A = [0, 99, 97, 97, 99, 100, 100, 0]
# sorted:
B = [0, 0, 97, 97, 99, 99, 100, 100]
此列表可以是回文,因为它可以重新排序为:

[0, 97, 99, 100, 100, 99, 97, 0]
我编写了以下代码,以在列表可以是回文时返回True

i=0
counter = 0

while i<len(B):
    if i+1 < len(B):
        if B[i]==B[i+1]:
            print(B[i],B[i+1])
            i+=2
        else:
            i+=1
            counter += 1
    else:
        i+=1

if counter<2:
    return True
return False
i=0
计数器=0

如果数字也需要按顺序排列(如
[1,1,2,2,3]
可以工作,但不是
[1,1,2,3,3]
),这里有一个简单的方法,它只需要按每2个字符分割排序的列表

def palindrome( input ):
    B = sorted(input)

    #Get every even index
    firstPart = B[::2]
    #Get every odd index
    secondPart = B[1::2]
    #Fix for if there's an odd number of indexes
    if len(secondPart) < len(firstPart):
        secondPart.append( B[-1] )
    #Return true or false
    return firstPart==secondPart


print palindrome( [0, 99, 97, 97, 99, 100, 0] )
#True
print palindrome( [0, 99, 97, 97, 99, 100, 100, 0] )
#True
print palindrome( [0, 94, 97, 97, 99, 100, 0] )
#False

计算每个值的出现次数。然后检查奇数计数的数量是否为零或一。没有必要对列表进行排序。这将适用于任何值列表

from collections import Counter

def can_be_palindrome(data):
    odd = (c % 2 for c in Counter(data).values())
    any(odd)  # skip first odd, if present at all
    return not any(odd)  # ensure no more odds

print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0]))  # only even counts, true
print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0, 1]))  # one odd count, true
print(can_be_palindrome([0, 99, 97, 97, 99, 100, 100, 0, 1, 2]))  # two odd counts, false
print(can_be_palindrome('abcabcd'))  # true
print(can_be_palindrome(['a', 'b', 'a', 1, 1])  # true

当我们遍历
B
时,我们可以使用集合来跟踪到目前为止哪些元素具有奇数(在这里使用集合比使用列表快得多):

然后,如果
赔率
的长度为0或1,则打印
True
。否则打印
False

print len(odds) <= 1 # prints the value you're looking for
print len(赔率)一个快速的(或者我认为是这样):使用字典来计算
odd
值。将值存储为字典中的键,如果键出现奇数次,则值为
True
,如果键出现偶数次,则值为
False
。最后返回True,即
.values()
只有0或1个
True
元素(也就是说,只有0或1个元素出现奇数次)

迭代器以短路方式工作。第一个
any
在满足第一个
True
时将返回
True
,否则它将扫描整个迭代器。然后我们重新运行
any(odd_iter)
——如果迭代器生成另一个True(也称奇数值),则返回
True
。如果第一个
any
耗尽迭代器,那么第二个
any
将直接返回
False
。最后,我们求反这个返回值,并从函数返回它

def check_palindrome_sequence(sequence):
    odds = {}
    for i in sequence:
        try:
            odds[i] ^= True
        except KeyError:
            odds[i] = True

    odd_iter = iter(odds.values())
    any(odd_iter)
    return not any(odd_iter)

A = [0, 99, 97, 97, 99, 100, 100, 0]
print(check_palindrome_sequence(A))  # True

A = [0, 99, 97, 97, 99, 100, 100, 0, 1]    
print(check_palindrome_sequence(A))  # True

A = [0, 99, 97, 97, 99, 100, 100, 0, 1, 2]
print(check_palindrome_sequence(A))  # False

Python 2.7上的计时:

In [1]: %timeit antti(ls)
1 loops, best of 3: 128 ms per loop

In [2]: %timeit davidism(ls)
10 loops, best of 3: 103 ms per loop

In [3]: %timeit leek(ls)
10 loops, best of 3: 42.1 ms per loop
所有3项的数据都是相同的:

ls = list(range(100000))
ls *= 2
ls += [ 1, 2 ]
random.shuffle(ls)
在Python3上计时,数据同样相同:

In [1]: %timeit leek(ls)
10 loops, best of 3: 37.4 ms per loop

In [2]: %timeit antti(ls)
10 loops, best of 3: 89.3 ms per loop

In [3]: %timeit davidism(ls)
10 loops, best of 3: 52 ms per loop
韭菜的是最好的完全随机整体。nettux的答案是二次减速,100000*2+2元素需要一分钟,我没有耐心计时

对于回文的小值来说,韭菜几乎是赢家

In [1]: %timeit leek(ls)                         
100000 loops, best of 3: 2.21 µs per loop

In [2]: %timeit antti(ls)
100000 loops, best of 3: 5.52 µs per loop

In [3]: %timeit davidism(ls)
100000 loops, best of 3: 7.45 µs per loop

在python中检查回文可以通过使用
l==l[::-1]
来完成。在
i+1
行中缺少一个“=”。应该是
i+=1
@g.d.d.c假设我的列表如示例中所示,因此我不能反向,但我需要检查数字是否成对或成对+1额外元素计数元素出现的数量。如果有一个元素出现奇数次,其余元素出现偶数次,或者每个元素出现偶数次,那么您的列表可以重新排序以形成回文,只有在元素奇数的情况下,中心元素是最大的回文才适用。请尝试[1,1,2,3,3]为什么?如果重新排序,它可能会形成回文:[1,3,2,3,1]哦,我现在明白了啊哈,我想它必须按顺序排列:)你介意添加一个编辑吗?这可能会导致一些混乱。这对偶数序列非常有效,但如果中心确实不是最大的元素,则对奇数序列无效。@Leekai在天空中再进行一次优化,您可以执行
remove=赔率。remove
add=赔率。add
以挤出更多性能。啊,我使用的是Python 2.7.9,这就解释了区别。谢谢
ls = list(range(100000))
ls *= 2
ls += [ 1, 2 ]
random.shuffle(ls)
In [1]: %timeit leek(ls)
10 loops, best of 3: 37.4 ms per loop

In [2]: %timeit antti(ls)
10 loops, best of 3: 89.3 ms per loop

In [3]: %timeit davidism(ls)
10 loops, best of 3: 52 ms per loop
In [1]: %timeit leek(ls)                         
100000 loops, best of 3: 2.21 µs per loop

In [2]: %timeit antti(ls)
100000 loops, best of 3: 5.52 µs per loop

In [3]: %timeit davidism(ls)
100000 loops, best of 3: 7.45 µs per loop