为了账号安全,请及时绑定邮箱和手机立即绑定

算法之数学自由组合问题(从M个不重复的数字中选取N个数字进行自由组合)

标签:
数据结构

今天,遇到一个同事的问题,要求给定从给定的5个不重复的数字中,取出3个数字,输出所有的组合情况。其实就是数学中的组合问题。以前仅仅做的是关于求出组合的情况数,这个很简单,用递归就可以求解。这题要求列举出所有情况。在网上进行一阵狂搜,最后找到了一个比较好理解的算法,叫“二进制置换算法”,先姑且这样叫吧。算法思想如下:
1、先定义一个数组,用1和0进行组合。其中1和0的总数为5个(即M),1表示命中(或被选中),所以1的总数为3(N)个。
2、那么初始状态可以设置为11100,称为一个状态码。
3、对初始状态是5选3的一种状态,再对这种状态进行后续分析。
4、分析如下:
a.从左到右,遇到第一次出现的10组合时,将其置为01。
b.判断最左边的第1位,如果为1,继续重复a步骤。如果为0,则将置换点之前的1移动到最左边。然后,再重复a步骤。
c.所有情况置换结束的条件是不再出现10组合,即表示已经得到了所有的情况。
5、根据第4步得到的所有状态码进行分析,将所有为1的位置,输出数组中对应的信息,即可得到一个数组的所有情况。
例如:
1 1 1 0 0
1 1 0 1 0
1 0 1 1 0
0 1 1 1 0
1 1 0 0 1
1 0 1 0 1
0 1 1 0 1
1 0 0 1 1
0 1 0 1 1
0 0 1 1 1//该状态码中不再出现10信息,即置换结束
代码如下:

public class Util {  
    //构造2进制字符串  
        public static String stringConstruction(int m,int n){  
            String testsString="";  
            for(int i=1;i<=m;i++){  
                if(i>n)  
                    testsString=testsString+"0";  
                else   
                    testsString=testsString+"1";  
            }  
            return testsString;  
        }  

        //二进制置换算法  
        public static List<String> allConditons(String s){  
            List<String> list = new ArrayList<String>();  
            list.add(s);  
            //;  
            while(true){  
                int length = list.size()-1;  
                //标志位  
                int flag = list.get(length).indexOf("10");  
                if(flag<0)  
                    break;  
                //先取最后一个元素  
                String last =list.get(length);  
                //判断该元素第1位字符  
                if(last.indexOf("0")>0){  
                    list.add(last.replaceFirst("10", "01"));  
                }  
                else {  
                    //先将10变成01  
                    String ss = last.replaceFirst("10", "01");  
                    //将10前面的内容反置  
                    String before = last.substring(0,last.indexOf("10"));  
                    StringBuffer sb = new StringBuffer(before);  
                    String after=sb.reverse().toString();  
                    list.add(ss.replaceFirst(before, after));  
                }  
            }  

            return list;  
        }  
        //通过置换算法获取自由组合  
        public static List<String> result(String[] r,List<String> list){  
            List<String> ttList =new ArrayList<String>();  

            for(int i=0;i<list.size();i++){  
                String eleString = list.get(i);  
                String temp="";  
                for(int j=0;j<eleString.length();j++){  
                    if(eleString.charAt(j)=='1')  
                        temp=temp+r[j]+" ";  
                }  
                ttList.add(temp);  
            }  
            //ttList去重操作,通过HashSet去重  
            HashSet<String> hs = new HashSet<String>(ttList);  
            ttList.clear();  
            ttList.addAll(hs);  
            return ttList;  
        }  
}  
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消