• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程问答 > 算法集合的所有子集全排列

算法集合的所有子集全排列

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-07

佚名通过本文主要向大家介绍了求集合子集的算法,子集算法,用c 算法求子集,子集和问题算法,子集构造算法等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题:算法 集合的所有子集 全排列
描述:

{1,2,3} 的所有排列组合方式
{{1},{2},{3}}

{{1},{2,3}}

{{1,2},{3}}

{{1,3},{2}}

{{123}}
请大家给个想法 或者 算法实现


解决方案1:

用位向量啊
若对应位置1,则表示后面插一个板

def work(n):
    for vector in xrange(1<<(n-1)):
        result = []
        for i in xrange(n):
            result.append(str(i+1))
            if (1 << i) & vector:
              result.append('|')
        print ' '.join(result)

work(3)

output:

1 2 3
1 | 2 3
1 2 | 3
1 | 2 | 3

解决方案2:

1、深度优先搜索实现
2、状态压缩用位表示集合

int set = (1<<n)-1;// 1111111....
for (int sub = set; sub; sub = set & (sub-1)) {
    //....
}

可以实现对一个集合的所有子集的枚举

解决方案3:

递归大法好:

def sub_sets(a):
    """
    find out all sub sets of specified collection.
    :param: a  - a set of elements
    :return: - a list of sub-sets. Each sub-set is a list of sets.
    """
    if len(a) == 0:
        return [] # empty set has no sub-sets
    elif len(a) == 1:
        return [[a]]
    else:
        x = a.pop()
        rest_sub_sets = sub_sets(a)

        # add single subset {x}
        all_sub_sets = [copy_list_add(m, {x}) for m in rest_sub_sets ]

        # add single element x to all subsets
        for ss in rest_sub_sets:
            for i in range(0, len(ss)):
                ss_copy = ss[:]
                ss_copy[i] = ss_copy[i].copy()
                ss_copy[i].add(x)
                all_sub_sets.append(ss_copy)

        return all_sub_sets

def copy_list_add(a, x):
    a_copy = a[:]
    a_copy.append(x)
    return a_copy

附测试代码:


def sub_sets_to_str(a):
    lines = []
    for l in a:
        parts = []
        for s in l:
            parts.append('{%s}' % ','.join(sorted(map(str, list(s)))))

        lines.append('[%s]' % ', '.join(sorted(parts)))

    return "\n".join(sorted(lines))

class SubSetTestCase(unittest.TestCase):
    def testEmpty(self):
        self.assertSubSetsEqual([], sub_sets(set()))

    def testOne(self):
        self.assertSubSetsEqual([[{1}]], sub_sets({1}))

    def testTwo(self):
        self.assertSubSetsEqual([
            [{1}, {2}],
            [{1,2}]
        ], sub_sets({1,2}))

    def testThree(self):
        result = [
            [{1}, {2}, {3}],
            [{1}, {2,3}],
            [{1,2}, {3}],
            [{1,3}, {2}],
            [{1,2,3}]
        ]
        self.assertSubSetsEqual(result, sub_sets({1,2,3}))

    def testFour(self):
        result = [
            [{1,2,3,4}],
            [{1}, {2,3,4}],
            [{1,2}, {3,4}],
            [{1,2,3}, {4}],
            [{1,3}, {2,4}],
            [{1,4}, {2,3}],
            [{1}, {2}, {3,4}],
            [{1,2}, {3}, {4}],
            [{1,3}, {2}, {4}],
            [{1,4}, {2}, {3}],
            [{1}, {2,3}, {4}],
            [{1}, {2}, {3}, {4}],
        ]
        self.assertSubSetsEqual(result, sub_sets({1,2,3,4}))

    def assertSubSetsEqual(self, a, b):
        a_str = sub_sets_to_str(a)
        b_str = sub_sets_to_str(a)
        if 1 or a_str != b_str:
            print
            print ' --- a --- '
            print a_str
            print ' --- b --- '
            print b_str
        return unittest.TestCase.assertEqual(self, a_str, b_str)


if __name__ == '__main__':
    unittest.main()

测试结果:


 --- a --- 

 --- b --- 

.
 --- a --- 
[{1,2,3,4}]
[{1,2,3}, {4}]
[{1,2}, {3,4}]
[{1,2}, {3}, {4}]
[{1,3}, {2,4}]
[{1,3}, {2}, {4}]
[{1,4}, {2,3}]
[{1,4}, {2}, {3}]
[{1}, {2,3,4}]
[{1}, {2,3}, {4}]
[{1}, {2}, {3,4}]
[{1}, {2}, {3}, {4}]
 --- b --- 
[{1,2,3,4}]
[{1,2,3}, {4}]
[{1,2}, {3,4}]
[{1,2}, {3}, {4}]
[{1,3}, {2,4}]
[{1,3}, {2}, {4}]
[{1,4}, {2,3}]
[{1,4}, {2}, {3}]
[{1}, {2,3,4}]
[{1}, {2,3}, {4}]
[{1}, {2}, {3,4}]
[{1}, {2}, {3}, {4}]
.
 --- a --- 
[{1}]
 --- b --- 
[{1}]
.
 --- a --- 
[{1,2,3}]
[{1,2}, {3}]
[{1,3}, {2}]
[{1}, {2,3}]
[{1}, {2}, {3}]
 --- b --- 
[{1,2,3}]
[{1,2}, {3}]
[{1,3}, {2}]
[{1}, {2,3}]
[{1}, {2}, {3}]
.
 --- a --- 
[{1,2}]
[{1}, {2}]
 --- b --- 
[{1,2}]
[{1}, {2}]
.
----------------------------------------------------------------------
Ran 5 tests in 0.006s

OK

解决方案4:

public class Solution {

public List<List<Integer>> permute(int[] num) {
    List<List<Integer>> result = new ArrayList<List<Integer>>();
    permute(result, num, 0);
    return result;
}

private void permute(List<List<Integer>> result, int[] array, int start) {
    if (start >= array.length) {
        List<Integer> current = new ArrayList<Integer>();
        for (int a : array) {
            current.add(a);
        }
        result.add(current);
    } else {
        for (int i=start; i<array.length; i++) {
            swap(array, start, i);
            permute(result, array, start+1);
            swap(array, start, i);
        }
    }
}

private void swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

}

解决方案5:

这个我想到高中的排列组合,用的是隔板法(不太记得是不是叫这个)。
比如,隔板是说在1|2|3|4 数字中间放的分隔板。
分成一个集合,不用隔板
分成两个集合,放一个隔板,共C(n-1,1),比如{1|234} {12|34} {123|4}
分成k个集合,放k-1个隔板,共C(n-1,k-1)种。

然后想如何实现隔板,给隔板编号1 , 2 , ... , n-1
于是每次放k个隔板意味着从n-1个数中取出k个数字,就是组合数,可以用回溯遍历出来

seq[] 放k的数字
seq[]=-1表示这个位置没有数字
DFS(index){
    if(index==k) {print(); return;}
    for(int i=1;i<=n-1;++i){
        if (seq[index]==-1 ){
            seq[index]=i; // 
            DFS(index+1)
            seq[index]=-1
        } 
    }
}
print(){
    int index=0;
    for(int i=1;i<=n;++i){
        printf(i);
        if(i==seq[index]){index++; print( | )}
    }
}
DFS(1)

讲的好,如果不存储全部的子集的话,每次维护/保存当前i的子集的序列,每次加一个i+1时,只需要输出i,和将i加到当前序列里面就可以了。

DFS(int num){
    print( {num} );
    for(int i=0;i<seq.size();++i){
        seq[i].add( num ); // 把num加入当前队列
        print( { );        // 便于显示观看
        for(intj=0;j<seq[i].size();++j)
            prinf( seq[i][j] );
        prinf( } );        // 便于显示观看
    }
    DFS(num+1);
}

如果不存储全部的子集的话,只需要复制seq,再添加num到其中一个seq中去即可,再加一个{num}。

咦?其实这个也可以直接一个循环,不用DFS还要浪费栈,因为num是从1到n没有变化的呀!

for (int num=1; num<=n; ++num)
{
    print( {num} );
    for(int i=0;i<seq.size();++i){
        seq[i].add( num ); // 把num加入当前队列
        print( { );        // 便于显示观看
        for(intj=0;j<seq[i].size();++j)
            prinf( seq[i][j] );
        prinf( } );        // 便于显示观看
    }
}

解决方案6:

public List<List<List<Integer>>> allSubsetPermutation(int[] nums){
    if(nums == null || nums.length == 0)
        return null;
    Queue<List<List<Integer>>> q = new LinkedList<>();
    q.add(new LinkedList<>());

    for(int n: nums){
        int size = q.size();
        while(size-- > 0){
            List<List<Integer>> list = q.poll();
            for(int i = 0; i < list.size(); i++){
                List<List<Integer>> l = deepClone(list);
                l.get(i).add(n);
                q.offer(l);
            }
            list.add(new LinkedList<>(Arrays.asList(n)));
            q.offer(list);
        }
    }
    return new LinkedList<>(q);
}

private List<List<In



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 算法集合的所有子集全排列

相关文章

  • 2017-06-07 最近上传更新很不稳定怎么回事
  • 2017-06-07 七牛抓取微信头像时返回错误代码:httpGeturlfailed:E502
  • 2017-06-07 python怎么用lxml处理
  • 2017-06-07 sebuf设置缓冲区大小,但并不是按照设定的大小刷新
  • 2017-06-07 分析Nginx的日志文件得到的IP来源为什么不正确?
  • 2017-06-07 python-ldap连接dn时报错
  • 2017-06-07 PHPcurl返回错误信息Failedwritingbody0!=3059
  • 2017-06-07 scala中,有什么方法,能够使得主程序在Actor执行了exit后才继续执行么~?
  • 2017-06-07 (python)我在阿里云上买了云服务,把html上传到什么位置可以访问?
  • 2017-06-07 如何写cookie注入工具,求思路!

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • phpsdk中policy上传策略返回值问题
    • 编程依赖数学知识吗?
    • 一个关于Token内含指令的设想
    • 用Python写了个程序调用word,运行完后再手动打开word文档就变慢了,这是为啥?
    • (python)Django175执行django-adminstartprojectmyblog出错
    • http://localhost:8080和http://localhost:8080/xxxx转换问题
    • 七牛iOSSDK是否处理502错误时代码不严谨?
    • (shell)为什么我的NERDTree没有配色和高亮啊
    • js中关于正则表达式奇怪的地方
    • XML解析关于XML解析替换指定内容的问题

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有