php - 给定一个字符串,返回所有的可能组合

查看:70
本文介绍了php - 给定一个字符串,返回所有的可能组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

例:abc
返回a,b,c,ab,ac,bc,ca,cb,abc,acb,bac,bca,cab,cba

解决方案

我覺得這個問題相當有趣,做為一個 Python 狂熱者,我不能同意 @garry_qian 的答案更多了,既然 Python 都提供了那麼好用的標準庫,不使用一下實在是太可惜了,在此立場下,一個 簡潔,簡短 (好啦並沒有...),但邏輯上基本相同的做法如下:

>>> s = 'abc'
>>> results = sorted([''.join(c) for l in range(len(s)) for c in permutations(s, l+1)])

['a', 'b', 'c', 'ab', 'ac', 'ba', 'bc', 'ca', 'cb', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba']

這個寫法沒什麼特別的,不過是使用兩個 forlist comprehension 罷了。
同時,它回傳的是一個 string 的 list,與原題目比較接近。


但是這激發了我的一些好奇心,想自己來寫寫看,同時以沒有這些排列組合工具的他種語言來說,也許比較容易利用相同的邏輯來完成。

首先我完成的是關於組合的 function,他代入一個字串並且回傳所有長度的所有字元組合,但不排列:

def get_combinations(string):
    combs = []
    for i in range(1, 2**len(string)):
        pat = "{0:b}".format(i).zfill(len(string))
        combs.append(''.join(c for c, b in zip(string, pat) if int(b)))
    return combs

測試:

>>> print get_combinations('abc')
['c', 'b', 'bc', 'a', 'ac', 'ab', 'abc']

一如預期,我們拿到:

  1. 長度為 1 的 'c', 'b', 'a'

  2. 長度為 2 的 'bc', 'ac', 'ab'

  3. 長度為 3 的 'abc'

果然是各種長度下的所有組合都到手了。

這個寫法肯定不是最好的,但我覺得想法滿有趣的。想法就是,要考慮 'abc' 的所有組合,那不就是分別考慮 a 要不要取,b 要不要取 和 c 要不要取,於是總共 2*2*2 = 8 (2**len(string)) 種組合,那不就正好對應到:

000 -> 都不取
001 -> 只取 c
010 -> 只取 b
011 -> 取 b c
100 -> 只取 a
101 -> 取 a c
110 -> 取 a b
111 -> 都取

所以在 get_combinations 中,用了一點技巧去生出從 1 到 7 的二進位碼,再根據 0 與 1 決定每一種組合該取用那些字元。


這還沒完成任務,我們距離標準答案,還必須取得:

每一種 組合 的所有 排列 情形

這產生了 get_permutations 這個 function:

def get_permutations(clst):
    if len(clst)==1:
        return [clst[0]]
    results = []
    for idx, c in enumerate(clst):
        results += [c+substr for substr in get_permutations(clst[:idx] + clst[idx+1:])]
    return results

測試:

>>> print get_permutations('abc')
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

邏輯很簡單,用 recursive 的方式去找出 固定長度字元組合 所有的排列。


有了以上兩種 function,我們就可以求出答案囉:

>>> [perm for comb in get_combinations('abc') for perm in get_permutations(list(comb))]
['c', 'b', 'bc', 'cb', 'a', 'ac', 'ca', 'ab', 'ba', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba']


結論:

  1. 別重複發明輪胎,這不但累死你,還很顯笨

  2. 人生苦短,我用 Python

这篇关于php - 给定一个字符串,返回所有的可能组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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