代码之家  ›  专栏  ›  技术社区  ›  E235

如何生成5个字符的字符串组合(1个数字,两个相等的字母和两个不同的相等的字母)而不重复

  •  0
  • E235  · 技术社区  · 6 年前

    例如 对的 组合:

    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  
    

    这是我正在使用的代码:

    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
    

    它显示我有79800个组合,但这是不正确的,因为我正在计算重复的组合:
    enter image description here

    a 出现两次然后重复字母,如 f ,出现两次,这样我们将得到如下结果: a3faf 但后来它选择了 字母as f 以及 再来一次 a3faf飞机

    enter image description here

    但不知道如何在我的代码中正确地执行它。

    你能建议我如何在我的代码中阻止它吗?意思是,得到的组合没有重复。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Steven Rumbalski    6 年前

    改变 permutations(letters, 2) combinations(letters, 2) . permutations() ('a', 'b') ('b', 'a') ,但是 combinations() 将交付公正的 (‘a’,‘b’) . 字母位置的组合会处理这些字母的所有顺序,因此您不需要看到它们两次。

    编辑: 除了之前的修正,基于第一个字母计算第二个字母的位置最终修正了它。所以如果 'a' 在索引处 0 2 然后 'b' 必须在索引处 1 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
    
        2
  •  1
  •   Ajax1234    6 年前

    #1aabb  
    #b1aab  
    #ca3ac  
    from collections import Counter
    LETTERS = 'bcdfghjklmnpqrstvwxz'
    DIGITS = '2456789'
    def combinations(d, current = []):
       if len(current) == 5:
          yield ''.join(current)
       else:
          for i in d:
            _d = Counter(current)
            if i.isdigit() and not any(c.isdigit() for c in current):
              yield from combinations(d, current+[i])
            elif (not current or _d.get(i, 0) == 1 or sum(c.isalpha() for c in current) < 2) and i.isalpha():
              yield from combinations(d, current+[i])
    
    result = list(combinations(LETTERS+DIGITS))
    

    输出(前100个结果):

    ['bcbc2', 'bcbc4', 'bcbc5', 'bcbc6', 'bcbc7', 'bcbc8', 'bcbc9', 'bcb2c', 'bcb4c', 'bcb5c', 'bcb6c', 'bcb7c', 'bcb8c', 'bcb9c', 'bccb2', 'bccb4', 'bccb5', 'bccb6', 'bccb7', 'bccb8', 'bccb9', 'bcc2b', 'bcc4b', 'bcc5b', 'bcc6b', 'bcc7b', 'bcc8b', 'bcc9b', 'bc2bc', 'bc2cb', 'bc4bc', 'bc4cb', 'bc5bc', 'bc5cb', 'bc6bc', 'bc6cb', 'bc7bc', 'bc7cb', 'bc8bc', 'bc8cb', 'bc9bc', 'bc9cb', 'bdbd2', 'bdbd4', 'bdbd5', 'bdbd6', 'bdbd7', 'bdbd8', 'bdbd9', 'bdb2d', 'bdb4d', 'bdb5d', 'bdb6d', 'bdb7d', 'bdb8d', 'bdb9d', 'bddb2', 'bddb4', 'bddb5', 'bddb6', 'bddb7', 'bddb8', 'bddb9', 'bdd2b', 'bdd4b', 'bdd5b', 'bdd6b', 'bdd7b', 'bdd8b', 'bdd9b', 'bd2bd', 'bd2db', 'bd4bd', 'bd4db', 'bd5bd', 'bd5db', 'bd6bd', 'bd6db', 'bd7bd', 'bd7db', 'bd8bd', 'bd8db', 'bd9bd', 'bd9db', 'bfbf2', 'bfbf4', 'bfbf5', 'bfbf6', 'bfbf7', 'bfbf8', 'bfbf9', 'bfb2f', 'bfb4f', 'bfb5f', 'bfb6f', 'bfb7f', 'bfb8f', 'bfb9f', 'bffb2', 'bffb4']
    
        3
  •  1
  •   MBo    6 年前

    对于固定长度和格式,此简单代码生成39900个组合:

    LETTERS = 'bcdfghjklmnpqrstvwxz'
    DIGITS = '2456789'
    
    def insdig(s, d):
        for i in range(5):
            ss = s[:i] + d + s[i:]
            print(ss)
    
    def aabb1():
        for dig in DIGITS:
            for i in range(len(LETTERS)-1):
                for j in range(i+1, len(LETTERS)):
                    a = LETTERS[i]
                    b = LETTERS[j]
                    insdig(a+a+b+b, dig)
                    insdig(a+b+a+b, dig)
                    insdig(b+a+a+b, dig)
                    insdig(a+b+b+a, dig)
                    insdig(b+a+b+a, dig)
                    insdig(b+b+a+a, dig)
    
    aabb1()