目录
回复内容:
首页 后端开发 php教程 给定一个字符串,返回所有的可能组合

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

Jul 06, 2016 pm 01:52 PM
php python

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

回复内容:

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

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

<code>>>> 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']</code>
登录后复制

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


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

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

<code>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</code>
登录后复制

測試:

<code>>>> print get_combinations('abc')
['c', 'b', 'bc', 'a', 'ac', 'ab', 'abc']</code>
登录后复制

一如預期,我們拿到:

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

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

  3. 長度為 3 的 'abc'

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

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

<code>000 -> 都不取
001 -> 只取 c
010 -> 只取 b
011 -> 取 b c
100 -> 只取 a
101 -> 取 a c
110 -> 取 a b
111 -> 都取</code>
登录后复制

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


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

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

這產生了 get_permutations 這個 function:

<code>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</code>
登录后复制

測試:

<code>>>> print get_permutations('abc')
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']</code>
登录后复制

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


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

<code>>>> [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']</code>
登录后复制

結論:

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

  2. 人生苦短,我用 Python

<code>import itertools

chrs = 'abc'

for i in range(len(chrs)):
    for combination in itertools.permutations(chrs, i + 1):
        print combination</code>
登录后复制

既然同时打了 phppython 标签,那就用两种方式都写下吧,逻辑用的一样的。

php代码

function addChar($strs, $chars) {
    $result = [];
    foreach ($strs as $str) {
        foreach ($chars as $char) {
            $result[] = $str . $char;
        }
    }
    return $result;
}

$chars  = ['a', 'b', 'c'];

$group = [];
$count = count($chars);
for ($i = 1; $i <= $count; $i++) { 
    if ($i == 1) {
        $group[$i] = addChar([''], $chars);
    } else {
        $group[$i] = addChar($group[$i - 1], $chars);
    }
}

// 合并数组
$result = call_user_func_array('array_merge', $group);

var_dump($group);
登录后复制

python代码

# encoding:utf-8

def addChar(strs, chars):
    result = []
    for str in strs:
        for char in chars:
            result.append(str + char)
    return result



chars = ['a', 'b', 'c']

group = {}
count = len(chars)

for i in xrange(1, count + 1):
    if i == 1:
        group[i] = addChar([''], chars)
    else:
        group[i] = addChar(group[i - 1], chars)

# 合并数组
result = []
for i in group:
    result += group[i]

print result
登录后复制

<code>result = [] 

def function(arg, string):
    global result

    if len(arg) >= len(string):
        return None 

    for alphabet in string:
        if alphabet in arg:
            continue
        function(arg+alphabet, string)
        result.append(arg+alphabet)

string = 'abc'

for alphabet in string:
    result.append(alphabet)
    function(alphabet, string)

print list(set(result))</code>
登录后复制

python2.7,和@garry_qian 相同,写完才发现有了,其他楼的python方案我都懒得看了

# coding: utf-8
import itertools as t

li = ['a', 'b', 'c']
tmp = []
for n in range(1, len(li) + 1):
    x = t.permutations(li, n)
    for i in x:
        tmp.append(''.join(i))
print tmp
登录后复制

P(2,3)
P(3,3)
12种可能性

假设字符串的长度为2, 那所有的组合就是: 2! + 2! / 1! = 4
假设字符串的长度为3, 那所有的组合就是: 3! + 3! / 1! + 3! / 2! = 15
假设字符串的长度为4, 那所有的组合就是: 4! + 4! / 1! + 4! / 2! + 4! / 3! = 64
这个公式可以进行推广
n! + n! / 1! + n! / 2! + ... + n! / (n-1)!

代码就不贴了

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1674
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Python vs. JavaScript:开发环境和工具 Python vs. JavaScript:开发环境和工具 Apr 26, 2025 am 12:09 AM

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

Python vs. C:了解关键差异 Python vs. C:了解关键差异 Apr 21, 2025 am 12:18 AM

Python和C 各有优势,选择应基于项目需求。1)Python适合快速开发和数据处理,因其简洁语法和动态类型。2)C 适用于高性能和系统编程,因其静态类型和手动内存管理。

Golang vs. Python:利弊 Golang vs. Python:利弊 Apr 21, 2025 am 12:17 AM

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Laravel vs. Python(与框架):比较分析 Laravel vs. Python(与框架):比较分析 Apr 21, 2025 am 12:15 AM

Laravel适合团队熟悉PHP且需功能丰富的项目,Python框架则视项目需求而定。1.Laravel提供优雅语法和丰富功能,适合需要快速开发和灵活性的项目。2.Django适合复杂应用,因其“电池包含”理念。3.Flask适用于快速原型和小型项目,提供极大灵活性。

如果session_start()被多次调用会发生什么? 如果session_start()被多次调用会发生什么? Apr 25, 2025 am 12:06 AM

多次调用session_start()会导致警告信息和可能的数据覆盖。1)PHP会发出警告,提示session已启动。2)可能导致session数据意外覆盖。3)使用session_status()检查session状态,避免重复调用。

IIS和PHP的兼容性:深度潜水 IIS和PHP的兼容性:深度潜水 Apr 22, 2025 am 12:01 AM

IIS和PHP可以兼容,通过FastCGI实现。1.IIS通过配置文件将.php文件请求转发给FastCGI模块。2.FastCGI模块启动PHP进程处理请求,提高性能和稳定性。3.实际应用中需注意配置细节、错误调试和性能优化。

Python vs. JavaScript:比较用例和应用程序 Python vs. JavaScript:比较用例和应用程序 Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

Python项目是否需要进行分层? Python项目是否需要进行分层? Apr 19, 2025 pm 10:06 PM

Python项目中的分层结构探讨在学习Python的过程中,很多初学者会接触到一些开源项目,特别是使用Django框架的项...

See all articles