【问题标题】:Removing consecutive characters from permutation从排列中删除连续字符
【发布时间】:2021-03-16 12:08:20
【问题描述】:

我有一个非常简单的排列脚本来将排列写入文件和一个计时器来说明脚本需要多长时间才能完成。

from itertools import permutations  
import time
start_time = time.time()
str = '012345'

file=open("p1.txt","a")
perm = permutations(str, 6)  
    
for i in perm:  
    file.write(''.join(i))
    file.write('\n')
else:
    print("--- %s seconds ---" % (time.time() - start_time))
file.close()

它给了我 012345 的所有排列。我想尝试并实现的是删除连续的字符,包括前后。

例如,如果排列是 05314,那就没问题了。非字符是连续的,无论是向前还是向后。但是,如果排列是 (a) 05324 或 (b) 05231,则这些都不行,因为 (a) 2 中的 3 向后,而 (b) 3 中的 2 向前。

这样的事情可能吗?谢谢。

【问题讨论】:

  • 您希望 (1) 删除连续字符,还是 (2) 如果找到连续字符则删除整个字符串? IOW,你提到的违规者的输出应该是什么?
  • 因此,如果遇到052341,那么删除3 是否满足您的要求,或者您是否希望删除34?如果要删除34,那么您将留下0521,那么它是否需要重新处理?
  • 您的代码有效吗?您有 str = '012345' 掩盖了内置函数。但是,稍后您尝试使用带有 file.write(str(i)) 的内置函数。
  • 对不起,我在这里很新,不确定我是否可以引用个别 cmets....但无论如何; jpf / MonekyZeus - 如果出现连续字符,我希望从输出中删除该行,而不仅仅是删除违规字符。 DarrylG - 很好……我会从我的涂鸦中删除错误的线条;我应该留在 file.write(''.join(i)) ...我已经编辑了上面的代码,谢谢。

标签: python permutation


【解决方案1】:

修改代码以过滤掉排列中的连续对

from itertools import permutations  
import time

start_time = time.time()
s = '012345'            # Don't use str = ... since its masks the builtin function

with open("p1.txt","a") as file:
    perm = permutations(s, 6)  

    for i in perm:  
        if not any(abs(ord(a)-ord(b))==1 for a, b in zip(i, i[1:])):
            # Does not have any consecutive pairs in i
            file.write(str(i))
            file.write('\n')
    else:
        print("--- %s seconds ---" % (time.time() - start_time))

说明

总体思路

  • 当且仅当 (iff) abs(a-b) == 1 时,数字对 (a, b) 是连续递增/递减的。
  • 如果列表中有连续的增加/减少对,则列表至少有一对连续的增加/减少对。

理念的应用

给定列表 lst,我们可以使用 zip 找到所有连续的对,即 zip(lst, lst[1:])

所以连续对列表是:

 [(a, b) for a, b in zip(lst, lst[1:])]

所有连续的增加/减少的对是:

[(a, b) for a, b in zip(lst, lst[1:]) if abs(a-b)== 1]

我们只关心此列表中是否至少有一对。我们可以为此使用 any,即

any(abs(a-b) == 1 for a, b in zip(lst, lst[1:]))

以上适用于数字列表,但我们必须对数字列表进行微调。

any(abs(ord(a) - ord(b)) == 1 for a, b in zip(lst, lst[1:]))

这通过检查两个字符串数字是否相隔一个来工作,方法是检查它们的 Unicode 十进制表示是否相隔一个。 Unicode 十进制由 ord 函数提供。注意数字“0”到“9”具有Unicode十进制48到57 List of Unicode characters

【讨论】:

  • 看起来它可以工作,谢谢 :-) 我要查找“如何”工作,因为该功能对我来说是新的,但它似乎完全符合我的要求为!
  • @Darren——添加了解释。这有帮助吗?
  • 谢谢,非常感谢,并为我的其他想法打下了良好的基础。
  • @Darren——你可以尝试回溯。 Python 排列速度很快,因为它是implemented in c。但是,如果您对排列有限制,我有时会发现当约束消除了大部分排列时,使用回溯可以更快地使用 Python 代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2018-10-21
  • 2019-11-29
  • 2011-05-21
相关资源
最近更新 更多