如何不重复地生成5个字符的字符串组合(1个数字,两个相等的字母和两个不同的相等的字母) [英] How to generate 5-character strings combinations (1 digit, two equal letters and two different equal letters) without duplication

查看:118
本文介绍了如何不重复地生成5个字符的字符串组合(1个数字,两个相等的字母和两个不同的相等的字母)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图生成一个由5个字符组成的字符串的组合,该字符串由四个字母(正好两个相等,另一个重复的两个相等)和一个数字组成.

I am trying to generate combinations of a 5-character strings consisting of four letters (exactly two are equal and another repeated two are equal) and one digit.

正确组合的示例:

1aabb  
b1aab  
ca3ac  

不正确组合的示例:

1aaaa  -> incorrect because there are more than 2 equal letters
1aaab  -> Same as the previous
1abcd  -> No 2 equal letters + 2 equal different letters  

这是我正在使用的代码:

This is the code I am using:

from itertools import combinations, permutations, product

LETTERS = 'bcdfghjklmnpqrstvwxz'
DIGITS = '2456789'

def aabb1(letters=LETTERS, digits=DIGITS):
    """Generate the distinct 5-character strings consisting of four
    letters (exactly two are equal and another repeat two are equal) and one digit.

    """
    combs = []
    for (a, b), (i, j), (x, y), d, k in product(
            permutations(letters, 2),   # Two letters (a repeated).
            combinations(range(4), 2),  # Positions for the repeated letter.
            combinations(range(2), 2),  # Positions for the second repeated letter.
            digits,                     # One digit.
            range(5)):                  # Positions for the digit.
        result = []
        result[i:i] = a,
        result[j:j] = a,
        result[x:x] = b,
        result[y:y] = b,
        result[k:k] = d,
        combs.append(''.join(result))

    print(len(combs))
    return combs

它打印出我有79,800个组合,但这是不正确的,因为我正在计算重复的组合:

It prints that I have 79,800 combinations but this is incorrect because I am counting duplicated combinations:

问题是因为它选择某个字母,例如a出现两次,然后重复出现字母,例如f,出现两次,所以我们会得到类似的内容:a3faf,但是后来它选择了第一个字母为f第二个字母为a,然后再次获得a3faf.
在数学中,我可以通过除以2来解决它:

The problem is because it chooses some letter, for example a to appear twice and then repeated letter, like f, to appear twice so we will get something like: a3faf but later it chooses the first letter as f and the second as a and get again a3faf.
In math I can solve it with dividing by 2:

但不确定如何在我的代码中正确执行此操作.

But not sure how to do it properly in my code.

您能在我的代码中建议如何防止它吗?意思是,获得没有重复的组合.

Can you suggest how I can prevent it in my code ? Meaning, get the combinations without duplication.

推荐答案

permutations(letters, 2)更改为combinations(letters, 2). permutations()将提供('a', 'b')('b', 'a'),但是combinations()将仅提供('a', 'b').字母位置的组合会处理这些字母的所有顺序,因此您无需两次查看它们.

Change permutations(letters, 2) to combinations(letters, 2). permutations() will deliver ('a', 'b') and ('b', 'a'), but combinations() will deliver just ('a', 'b'). Your combinations for letter positions takes care of all orderings of those letters so you don't need to see them twice.

编辑:除了上一个修复程序之外,最后根据第一个字母计算第二个字母的位置也将其修复.因此,如果'a'位于索引02,则'b'必须位于索引14.

In addition to the previous fix, calculating the positions of the second letter based on the first letter finally fixes it. So if 'a' is at index 0 and 2 then 'b' must be at index 1 and 4.

def aabb1(letters=LETTERS, digits=DIGITS):
    """Generate the distinct 5-character strings consisting of four
    letters (exactly two are equal and another repeat two are equal) and one digit.

    """
    letterdxs = set(range(4))
    combs = []
    for (a, b), (i, j), d, k in product(
            combinations(letters, 2),   # Two letters (a repeated).
            combinations(range(4), 2),  # Positions for the 1st repeated letter.
            digits,                     # One digit.
            range(5)):                  # Positions for the digit.
        x, y = letterdxs.difference((i, j))
        result = []
        result[i:i] = a,
        result[j:j] = a,
        result[x:x] = b,
        result[y:y] = b,
        result[k:k] = d,
        combs.append(''.join(result))
    print(len(combs))
    return combs

这篇关于如何不重复地生成5个字符的字符串组合(1个数字,两个相等的字母和两个不同的相等的字母)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆