python 实现求一个集合的子集
概要
今天偶然看到有个关于数学中集合的问题,就突发奇想的想用python实现下求一个集合的子集。
准备
我当然先要复习下,什么是集合,什么是子集?
比较粗犷的讲法,集合就是一堆确定的东西,细致一点的讲法呢,就是由一个或多个确定的元素所构成的整体,集合中的东西称为元素。
集合有一些特性:
1.确定性
给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。
2.互异性
一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。有时需要对同一元素出现多次的情形进行刻画,可以使用多重集,其中的元素允许出现多次。
3.无序性
一个集合中,每个元素的地位都是相同的,元素之间是无序的。集合上可以定义序关系,定义了序关系后,元素之间就可以按照序关系排序。但就集合本身的特性而言,元素之间没有必然的序。
集合也有些相关的概念:
1.空集
这类集合不包含任何元素,它是任何一个非空集合的真子集,同时它也是任何一个集合的子集。
2.子集
如果有两个集合,S,T,对于S中的任何一个元素,都能在T中找到,那么称S是T的子集
3.真子集
如果有两个集合,S,T,其中,S是T的子集,但是在T中存在元素不属于S,那么称S是T的真子集。
例子
下面我们就举个例子来具体说明下。
假设有集合 S=(a,b,c)
那么它的子集是(a)(b)(c)(a,b)(a,c)(b,c)(a,b,c)()
真子集是 (a)(b)(c)(a,b)(a,c)(b,c)()
我们可以看出这样一个规律(当然,简单的通过这样一个例子,好像并不能),就是假设集合中元素的个数是N,那么它子集的个数是 2N个,真子集的个数是2N-1个。
这个使我们根据定义通过主观的意识去判断的,通过代码该如何实现呢?
python实现
之前听到过一句话,talk is cheap,show me the code,说起来都是很简单的,代码实现呢?
上代码之前,先简单讲一下这其中的一些算法,通过之前的讲解,很容易就知道,对于一个集合中的元素,要么在它的集合中,要么不在,我们是不是可以利用0和1来表示,
比如上面的集合S,我们就来试一下,
(a) --> (100)=4
(b) --> (010)=2
(c) --> (001)=1
(a,b) --> (110)=6
(a,c) --> (101)=5
(b,c) --> (011)=3
(a,b,c)--> (111)=7
() --> (000)=0
是不是具有一定的规律?
我们就来实现下:
# -*- coding: utf-8 -*- list_demo = ['a', 'b', 'c'] sub_list_all = [] # 用于存放集合所有的子集 for i in range(1 << len(list_demo)): # 循环遍历0到2**n之间的每个数 combo_list = [] # 用于存放每个单独的循环中取出的子集 for j in range(len(list_demo)): if i & (1 << j): # 每一个数用&操作判断改为上是否有1 combo_list.append(list_demo[j]) # 有的话保存起来 sub_list_all.append(combo_list) print(len(sub_list_all))
运行下:
E:\pythonsource\venv\Scripts\python.exe E:/pythonsource/study/subsetCompute.py [[], ['a'], ['b'], ['a', 'b'], ['c'], ['a', 'c'], ['b', 'c'], ['a', 'b', 'c']] Process finished with exit code 0