排列列出随机结果

发布于 2025-02-04 04:04:18 字数 977 浏览 5 评论 0原文

有人可以帮助使用此代码,我需要它能够保存每个排列列表和每个数字,并打印随机的时间,让我们说20个。

现在,它仅适用于第一部分。 它打印了一个给定单词的排列,但是我不知道要整合所评论的下半部分,它必须进行计数并随机结果。

假设您需要“小鼠”的排列,应该出现24行,这应该是代码后半段的输入(最后6行)。使用sys.stdin,必须将这24行添加到计数列表中。结果,每行都会获取一个数字(1-24),然后将其中的20行随机选择(必须随机使用,必须随机使用)。

输入是一个单词, 输出必须为20个随机排列。

任何建议将不胜感激,谢谢。

import sys, re



def gen_permutations(a, n):
 
    if n == 0:
        print(''.join(a))
    else:
        for i in range(n):
            gen_permutations(a, n-1)
            j = 0 if n % 2 == 0 else i
            a[j], a[n] = a[n], a[j]
        gen_permutations(a, n-1)

if len(sys.argv) != 2:
    sys.stderr.write('one argument only\n')
    sys.exit(1)


word = sys.argv[1]

gen_permutations(list(word), len(word)-1)

#counts = {}
#for line in sys.stdin:
#     for word in re.findall(r'[a-z\']+', line.lower()):
#         counts[word] = counts.get(word, 0) + 1
#         for word, count in sorted(counts.items()):
#             print (word, count)



Can someone help with this code, i need it to be able to save a list of permutations and a number after each one, and to print random lets say 20 of them.

for now it works only for the first part..
it prints the permutations of a given word, but i don't know hot to incorporate the second half that is commented, it has to do counts and takes random results.

lets say you want the permutations of "mice", there are 24 rows that should appear, that should be the input for the second half of the code(last 6 rows). using sys.stdin these 24 rows have to be added to counts list.. Every row gets a number (1-24) and then 20 of those are chosen randomly (import math, random must be used) as a result.

input is one word,
output must be 20 random permutations.

Any advice will be appreciated, thanks.

import sys, re



def gen_permutations(a, n):
 
    if n == 0:
        print(''.join(a))
    else:
        for i in range(n):
            gen_permutations(a, n-1)
            j = 0 if n % 2 == 0 else i
            a[j], a[n] = a[n], a[j]
        gen_permutations(a, n-1)

if len(sys.argv) != 2:
    sys.stderr.write('one argument only\n')
    sys.exit(1)


word = sys.argv[1]

gen_permutations(list(word), len(word)-1)

#counts = {}
#for line in sys.stdin:
#     for word in re.findall(r'[a-z\']+', line.lower()):
#         counts[word] = counts.get(word, 0) + 1
#         for word, count in sorted(counts.items()):
#             print (word, count)



如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲸落 2025-02-11 04:04:18

作为替代答案,从更数学的角度来解决如何解决此问题:

from math import factorial
from random import sample


def solve(word, count):
    factorials = [factorial(x) for x in range(len(word))][::-1]
    indices = sample(range(factorial(len(word))), count)
    
    output = []
    for index in indices:
        alphabet = list(word)
        result = ""
        for fact in factorials:
            q, index = divmod(index, fact)
            result += alphabet.pop(q)
        output.append(result)
    return output

示例用法

>>> print(solve("abcde", 10))
['bdeca', 'bdcea', 'decba', 'caebd', 'daceb', 'cedba', 'cdbea', 'ebcda', 'decab', 'becad']

通过首先选择选择排列索引的方式,并计算与这些索引相关的排列。 n字符的排列具有n!排列,因此,如果我们的索引大于该索引,我们将需要附加字符。我们(从概念上)交换领先字符,减去我们跳过的n!排列,看看此新索引值是否小于n! - 冲洗并重复直到这是。然后,我们重复n-1,依此类推,直到我们构建了整个排列,然后为其余的索引进行操作。

索引映射i使用的相当于itertools.permutations的顺序,如果您有indices 的 [2,5,5,9] ,输出将与列表的2、5和9'元素相同(排列(...))

对于小样本量,此实现的速度要快得多,因为它的时间复杂性为o(c​​ * s) - 至少如果您使用足够小的数字,可以将乘法视为o(1)。否则,该阶乘预报将是时间复杂性的不可忽视的部分。

如果您需要按顺序排序的顺序,则可以在迭代之前对indices进行排序,并且结果将按顺序返回。

As an alternative answer, tackling how to approach this problem from a more mathematical perspective:

from math import factorial
from random import sample


def solve(word, count):
    factorials = [factorial(x) for x in range(len(word))][::-1]
    indices = sample(range(factorial(len(word))), count)
    
    output = []
    for index in indices:
        alphabet = list(word)
        result = ""
        for fact in factorials:
            q, index = divmod(index, fact)
            result += alphabet.pop(q)
        output.append(result)
    return output

Example usage

>>> print(solve("abcde", 10))
['bdeca', 'bdcea', 'decba', 'caebd', 'daceb', 'cedba', 'cdbea', 'ebcda', 'decab', 'becad']

The way this work is by first selecting indices of permutations to select, and the computes the permutations associated with those indices. A permutation of n characters has n! permutations, so if our index is larger than that, we are going to need an additional character. We (conceptually) swap out the leading character, subtract the n! permutations we skipped over, and see if this new index value is less than n! - rinse and repeating until it is. We then repeat on n-1, and so on, until we have built the entire permutation, and then do so for the rest of the indices.

The index mapping I use corresponds to the order of itertools.permutations as well- if you have indices of [2, 5, 9], the output will be the same as the 2, 5, and 9 'th elements of list(permutations(...)).

This implementation is much faster for small sample sizes, since its time complexity is O(C * S) - at least if you use small enough numbers that you can treat multiplication as O(1). Otherwise, that factorial pre-computation will be a non-negligible portion of the time complexity.

If you need your results in sorted order, you can sort indices before iterating, and the results will be returned in sorted order.

本王不退位尔等都是臣 2025-02-11 04:04:18
from itertools import permutations
from random import sample

word = ...

perms = sample(list(enumerate(permutations(word))), 20)
for id_val, perm in perms:
    print("".join(perm), id_val)

单词“ abcd”的输出:

bcad 8
bdca 11
cdba 17
cbad 14
acdb 3
adcb 5
abcd 0
dbac 20
dbca 21
cabd 12
abdc 1
bacd 6
cbda 15
cadb 13
badc 7
bdac 10
cdab 16
dcba 23
dcab 22
dacb 19

注释:此(以及您的原始实现)会生成所有排列,即使是在输出中未使用的排列。这意味着对于大单词,在本质上是O(n!),跑步将比必要的时间更长。

如果发现遇到性能问题,则应使用Random.Choices选择20 indices ,然后生成对应的与这些指数相对应的特定排列。您会找到Math.combMath.factorial对此有用。


要计算重复序列,您需要random.sample to random.choices(允许重复),然后使用collections.counter.counter计算他们。

from itertools import permutations
from random import choices
from collections import Counter

perms = choices(list(enumerate(permutations(word))), k=20)
counts = Counter(counts)

for perm, count in counts.items():
    print("".join(perm), count)
from itertools import permutations
from random import sample

word = ...

perms = sample(list(enumerate(permutations(word))), 20)
for id_val, perm in perms:
    print("".join(perm), id_val)

Output for word "abcd":

bcad 8
bdca 11
cdba 17
cbad 14
acdb 3
adcb 5
abcd 0
dbac 20
dbca 21
cabd 12
abdc 1
bacd 6
cbda 15
cadb 13
badc 7
bdac 10
cdab 16
dcba 23
dcab 22
dacb 19

Note: this (as well as your original implementation) generates all permutations, even those not used in the output. This means for large words, it will take a much longer time to run than necessary, being O(n!) in nature.

If you find that you run into performance issues, instead you should use random.choices to select 20 indices, and then generate corresponding those specific permutations corresponding to those indices. You'll find math.comb and math.factorial useful for this.


For counting repeats, you'll want to replace random.sample with random.choices (to allow repetition), and then use collections.Counter to count them.

from itertools import permutations
from random import choices
from collections import Counter

perms = choices(list(enumerate(permutations(word))), k=20)
counts = Counter(counts)

for perm, count in counts.items():
    print("".join(perm), count)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文