Python通過內(nèi)置函數(shù)和自寫算法DFS實(shí)現(xiàn)排列組合
排列組合是數(shù)學(xué)中的一種常見的計(jì)算方法,用于求出從給定的元素中選取若干個元素的所有可能的排列或組合。在Python中,有多種方式可以實(shí)現(xiàn)排列組合的計(jì)算。
本文將介紹兩種主要的方法:調(diào)用內(nèi)置函數(shù)和自寫算法DFS實(shí)現(xiàn)。
調(diào)用內(nèi)置函數(shù)
Python標(biāo)準(zhǔn)庫中提供了一個模塊itertools,該模塊包含了許多用于生成迭代器的工具函數(shù),其中就有2個函數(shù)可以用于計(jì)算排列組合,分別是:
- permutations(p [, r]):從序列p中取出r個元素的組成全排列,組合得到元組作為新迭代器的元素。
- combinations(p, r):從序列p中取出r個元素組成全組合,元素不允許重復(fù),組合得到元組作為新迭代器的元素。
這2個函數(shù)都返回一個迭代器對象,可以使用list()函數(shù)將其轉(zhuǎn)換為列表,或者使用for循環(huán)遍歷其元素。下面是一個簡單的例子:
對于1到n個數(shù)進(jìn)行排列,使用內(nèi)置函數(shù)permutations(iterable,r=None);
permutations(iterable,r=None) 連續(xù)返回iterable序列中的元素生成的長度為r的排列,如果r未指定或者為None,則默認(rèn)值為iterable的長度。
from itertools import * s = [1,2,3,4,5] for element in permutations(s,2): a = "".join(str(element)) print(a,end="") out[1]:(1, 2)(1, 3)(1, 4)(1, 5)(2, 1)(2, 3)(2, 4)(2, 5)(3, 1)(3, 2)(3, 4)(3, 5)(4, 1)(4, 2)(4, 3)(4, 5)(5, 1)(5, 2)(5, 3)(5, 4)
如果需要枚舉的數(shù)少的情況,可以直接通過暴力法
for i in range(5): for j in range(5): if i!=j: print(s[i],s[j])
暴力法對于數(shù)字少的情況,效果好且簡單。
對于1到n個數(shù)進(jìn)行組合,使用內(nèi)置函數(shù)combinations(iterable,r=None)
In [30]: from itertools import * s = {1,2,3,4} for element in combinations(s,3): a = "".join(str(element)) print(a,end="") (1, 2, 3)(1, 2, 4)(1, 3, 4)(2, 3, 4)
自寫算法DFS實(shí)現(xiàn)
除了使用內(nèi)置函數(shù)外,我們也可以自己編寫算法來實(shí)現(xiàn)排列組合的計(jì)算。一種常見的算法是使用深度優(yōu)先搜索(DFS)來遍歷所有可能的情況,并將滿足條件的結(jié)果保存下來。下面是一個使用DFS實(shí)現(xiàn)全排列和全組合的例子:
a = [1,2,3,4,5] def dfs(s,t): if s==2: for i in range(0,2): print(a[i],end="") print(" ") return for i in range(s,t+1): a[s],a[i] = a[i],a[s] dfs(s+1,t) a[s],a[i] = a[i],a[s] dfs(0,4)
上述代碼雖然很短,但有個缺點(diǎn)就是不能從小到大輸出排列。
改進(jìn)之后的代碼:實(shí)現(xiàn)從小到大輸出
a = [1,2,3,4,5] b = [0] * 10 vis = [0] * 20 def dfs(s,t): if s==2: for i in range(0,2): print(b[i],end="") print(" ") return for i in range(0,t): if not vis[i]: vis[i] = True b[s] = a[i] dfs(s+1,t) vis[i] = False dfs(0,5)
自寫算法實(shí)現(xiàn)組合:
# 首先,我們定義一個函數(shù)dfs,它接受五個參數(shù): # - cur: 當(dāng)前遍歷到的元素的下標(biāo),初始為0 # - m: 要選出的元素個數(shù) # - cur_list: 保存當(dāng)前已選出的元素的列表 # - original_list: 給定的n個元素的列表 # - result_list: 保存最終結(jié)果的列表 def dfs(cur, m, cur_list, original_list, result_list): # 如果已經(jīng)選出了m個元素,就把當(dāng)前列表添加到結(jié)果列表中,并返回 if m == 0: result_list.append(list(cur_list)) return # 如果還沒有選出m個元素,就從當(dāng)前下標(biāo)開始,遍歷原始列表中的每個元素 for i in range(cur, len(original_list)): # 把當(dāng)前元素添加到當(dāng)前列表中 cur_list.append(original_list[i]) # 遞歸地調(diào)用dfs函數(shù),更新下標(biāo)和剩余元素個數(shù) dfs(i + 1, m - 1, cur_list, original_list, result_list) # 回溯時(shí),把當(dāng)前元素從當(dāng)前列表中移除 cur_list.pop() # 然后,我們定義一個測試函數(shù),給定一個原始列表和一個目標(biāo)個數(shù),調(diào)用dfs函數(shù),并打印結(jié)果列表 def test(original_list, m): # 初始化結(jié)果列表為空列表 result_list = [] # 調(diào)用dfs函數(shù),傳入初始下標(biāo)為0,空的當(dāng)前列表和結(jié)果列表 dfs(0, m, [], original_list, result_list) # 打印結(jié)果列表 print(result_list) # 最后,我們用一個例子來測試一下我們的算法,假設(shè)原始列表為[1, 2, 3, 4],目標(biāo)個數(shù)為2 test([1, 2, 3, 4], 3) # 輸出結(jié)果為: # [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] # 可以看到,我們的算法成功地找到了所有的組合,并用DFS的方式遍歷了它們。
到此這篇關(guān)于Python通過內(nèi)置函數(shù)和自寫算法DFS實(shí)現(xiàn)排列組合的文章就介紹到這了,更多相關(guān)Python實(shí)現(xiàn)排列組合內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python簡單實(shí)現(xiàn)Base64編碼和解碼的方法
這篇文章主要介紹了Python簡單實(shí)現(xiàn)Base64編碼和解碼的方法,結(jié)合具體實(shí)例形式分析了Python實(shí)現(xiàn)base64編碼解碼相關(guān)函數(shù)與使用技巧,需要的朋友可以參考下2017-04-04pandas 數(shù)據(jù)歸一化以及行刪除例程的方法
今天小編就為大家分享一篇pandas 數(shù)據(jù)歸一化以及行刪除例程的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11python?中的np.zeros()和np.ones()函數(shù)詳解
這篇文章主要介紹了python?中的np.zeros()和np.ones()函數(shù),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04python使用multiprocessing的詳細(xì)方法
multiprocessing是Python標(biāo)準(zhǔn)庫中的一個模塊,用于實(shí)現(xiàn)多進(jìn)程編程,它提供了一種簡單而高效的方式來利用多核處理器的能力,通過在多個進(jìn)程中同時(shí)執(zhí)行任務(wù),加快程序的執(zhí)行速度和提高系統(tǒng)的吞吐量,這篇文章主要介紹了python使用multiprocessing,需要的朋友可以參考下2024-03-03Python實(shí)現(xiàn)完全數(shù)的示例詳解
完全數(shù),又稱完美數(shù),定義為:這個數(shù)的所有因數(shù)(不包括這個數(shù)本身)加起來剛好等于這個數(shù)。本文就來用Python實(shí)現(xiàn)計(jì)算完全數(shù),需要的可以參考一下2023-01-01使用Python求解最大公約數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了使用Python求解最大公約數(shù)的實(shí)現(xiàn)方法,包括用Python表示歐幾里得算法和Stein算法的求解原理,需要的朋友可以參考下2015-08-08詳解MySQL數(shù)據(jù)類型int(M)中M的含義
int(M)拆分來說,int是代表整型數(shù)據(jù)那,么中間的M應(yīng)該是代表多少位了,后來查mysql手冊也得知了我的理解是正確的,下面這篇文章小編就來舉例詳細(xì)說明。 文中介紹的很詳細(xì),相信對大家的理解和學(xué)習(xí)很有幫助,有需要的朋友們下面就來學(xué)習(xí)學(xué)習(xí)吧。2016-11-11