关于各种排列组合java算法实现方法

一.利用二进制状态法求排列组合,此种方法比较容易懂,但是运行效率不高,小数据排列组合可以使用


代码如下:

import java.util.Arrays;

//利用二进制算法进行全排列
//count1:170187
//count2:291656

public class test {
    public static void main(String[] args) {
        long start=System.currentTimeMillis();
        count2();
        long end=System.currentTimeMillis();
        System.out.println(end-start);
    }
    private static void count2(){
        int[] num=new int []{1,2,3,4,5,6,7,8,9};
        for(int i=1;i<Math.pow(9, 9);i++){
            String str=Integer.toString(i,9);
            int sz=str.length();
            for(int j=0;j<9-sz;j++){
                str="0"+str;
            }
            char[] temp=str.toCharArray();
            Arrays.sort(temp);
            String gl=new String(temp);
            if(!gl.equals("012345678")){
                continue;
            }
            String result="";
            for(int m=0;m<str.length();m++){
                result+=num[Integer.parseInt(str.charAt(m)+"")];
            }
            System.out.println(result);
        }
    }
    public static void count1(){
        int[] num=new int []{1,2,3,4,5,6,7,8,9};
        int[] ss=new int []{0,1,2,3,4,5,6,7,8};
        int[] temp=new int[9];
        while(temp[0]<9){
            temp[temp.length-1]++;
            for(int i=temp.length-1;i>0;i--){
                if(temp[i]==9){
                    temp[i]=0;
                    temp[i-1]++;
                }
            }
            int []tt=temp.clone();
            Arrays.sort(tt);
            if(!Arrays.equals(tt,ss)){
                continue;
            }
            String result="";
            for(int i=0;i<num.length;i++){
                result+=num[temp[i]];
            }
            System.out.println(result);

}
    }
}

二.用递归的思想来求排列跟组合,代码量比较大


代码如下:

package practice;

import java.util.ArrayList;
import java.util.List;

public class Test1 {

/**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Object[] tmp={1,2,3,4,5,6};
//        ArrayList<Object[]> rs=RandomC(tmp);
        ArrayList<Object[]> rs=cmn(tmp,3);
        for(int i=0;i<rs.size();i++)
        {
//            System.out.print(i+"=");
            for(int j=0;j<rs.get(i).length;j++)
            {
                System.out.print(rs.get(i)[j]+",");
            }
            System.out.println();

}
    }

// 求一个数组的任意组合
    static ArrayList<Object[]> RandomC(Object[] source)
    {
        ArrayList<Object[]> result=new ArrayList<Object[]>();
        if(source.length==1)
        {
            result.add(source);       
        }
        else
        {
            Object[] psource=new Object[source.length-1];
            for(int i=0;i<psource.length;i++)
            {
                psource[i]=source[i];
            }
            result=RandomC(psource);
            int len=result.size();//fn组合的长度
            result.add((new Object[]{source[source.length-1]}));
            for(int i=0;i<len;i++)
            {
                Object[] tmp=new Object[result.get(i).length+1];
                for(int j=0;j<tmp.length-1;j++)
                {
                    tmp[j]=result.get(i)[j];
                }
                tmp[tmp.length-1]=source[source.length-1];
                result.add(tmp);
            }

}
        return result;
    }

static ArrayList<Object[]> cmn(Object[] source,int n)
    {
        ArrayList<Object[]> result=new ArrayList<Object[]>();
        if(n==1)
        {
            for(int i=0;i<source.length;i++)
            {
                result.add(new Object[]{source[i]});

}
        }
        else if(source.length==n)
        {
            result.add(source);
        }
        else
        {
            Object[] psource=new Object[source.length-1];
            for(int i=0;i<psource.length;i++)
            {
                psource[i]=source[i];
            }
            result=cmn(psource,n);
            ArrayList<Object[]> tmp=cmn(psource,n-1);
            for(int i=0;i<tmp.size();i++)
            {
                Object[] rs=new Object[n];
                for(int j=0;j<n-1;j++)
                {
                    rs[j]=tmp.get(i)[j];
                }
                rs[n-1]=source[source.length-1];
                result.add(rs);
            }
        }
        return result;
    }

}

三.利用动态规划的思想求排列和组合


代码如下:

package Acm;
//强大的求组合数
public class MainApp {
    public static void main(String[] args) {
        int[] num=new int[]{1,2,3,4,5};
        String str="";
        //求3个数的组合个数
//        count(0,str,num,3);
//        求1-n个数的组合个数
        count1(0,str,num);
    }

private static void count1(int i, String str, int[] num) {
        if(i==num.length){
            System.out.println(str);
            return;
        }
        count1(i+1,str,num);
        count1(i+1,str+num[i]+",",num);
    }

private static void count(int i, String str, int[] num,int n) {
        if(n==0){
            System.out.println(str);
            return;
        }
        if(i==num.length){
            return;
        }
        count(i+1,str+num[i]+",",num,n-1);
        count(i+1,str,num,n);
    }
}

下面是求排列


代码如下:

package Acm;
//求排列,求各种排列或组合后排列
import java.util.Arrays;
import java.util.Scanner;

public class Demo19 {
    private static boolean f[];
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int sz=sc.nextInt();
        for(int i=0;i<sz;i++){
            int sum=sc.nextInt();
            f=new boolean[sum];
            Arrays.fill(f, true);
            int[] num=new int[sum];
            for(int j=0;j<sum;j++){
                num[j]=j+1;
            }
            int nn=sc.nextInt();
            String str="";
            count(num,str,nn);
        }
    }
    /**
     *
     * @param num 表示要排列的数组
     * @param str 以排列好的字符串
     * @param nn  剩下需要排列的个数,如果需要全排列,则nn为数组长度
     */
    private static void count(int[] num, String str, int nn) {
        if(nn==0){
            System.out.println(str);
            return;
        }
        for(int i=0;i<num.length;i++){
            if(!f[i]){
                continue;
            }
            f[i]=false;
            count(num,str+num[i],nn-1);
            f[i]=true;
        }
    }
}

(0)

相关推荐

  • 基于Java实现的图的广度优先遍历算法

    本文以实例形式讲述了基于Java的图的广度优先遍历算法实现方法,具体方法如下: 用邻接矩阵存储图方法: 1.确定图的顶点个数和边的个数 2.输入顶点信息存储在一维数组vertex中 3.初始化邻接矩阵: 4.依次输入每条边存储在邻接矩阵arc中 输入边依附的两个顶点的序号i,j: 将邻接矩阵的第i行第j列的元素值置为1: 将邻接矩阵的第j行第i列的元素值置为1: 广度优先遍历实现: 1.初始化队列Q 2.访问顶点v:visited[v]=1;顶点v入队Q; 3.while(队列Q非空) v=队列

  • java异或加密算法

    简单异或密码(simple XOR cipher)是密码学中中一种简单的加密算法. 异或运算:m^n^n = m; 利用异或运算的特点,可以对数据进行简单的加密和解密. 复制代码 代码如下: /** * 简单异或加密解密算法 * @param str 要加密的字符串 * @return */private static String encode2(String str) { int code = 112; // 密钥 char[] charArray = str.toCharArray(); 

  • Java实现的权重算法(按权重展现广告)

    基本算法描述如下: 1.每个广告增加权重 2.将所有匹配广告的权重相加sum, 3.以相加结果为随机数的种子,生成1~sum之间的随机数rd 4..接着遍历所有广告,访问顺序可以随意.将当前节点的权重值加上前面访问的各节点权重值得curWt,判断curWt >=  rd,如果条件成立则返回当前节点,如果不是则继续累加下一节点. 直到符合上面的条件,由于rd<=sum 因此一定存在curWt>=rd. 特别说明: 此算法和广告的顺序无关 import java.util.ArrayList

  • java字符串相似度算法

    本文实例讲述了java字符串相似度算法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: public class Levenshtein {     private int compare(String str, String target) {         int d[][]; // 矩阵         int n = str.length();         int m = target.length();         int i; // 遍历str的      

  • Java数据结构及算法实例:朴素字符匹配 Brute Force

    /** * 朴素字符串算法通过两层循环来寻找子串, * 好像是一个包含模式的"模板"沿待查文本滑动. * 算法的思想是:从主串S的第pos个字符起与模式串进行比较, * 匹配不成功时,从主串S的第pos+1个字符重新与模式串进行比较. * 如果主串S的长度是n,模式串长度是 m,那么Brute-Force的时间复杂度是o(m*n). * 最坏情况出现在模式串的子串频繁出现在主串S中. * 虽然它的时间复杂度为o(m*n),但在一般情况下匹配时间为o(m+n), * 因此在实际中它被大量

  • 关于JAVA经典算法40题(超实用版)

    [程序1]题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?1.程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21....public class exp2{ public static void main(String args[]){ int i=0; for(i=1;i<=20;i++)System.out.println(f(i));}public static int f(in

  • Android Java实现余弦匹配算法示例代码

     Java实现余弦匹配算法 最近在做一个通讯交友的项目,项目中有一个这样的需求,通过用户的兴趣爱好,为用户寻找推荐兴趣相近的好友.其实思路好简单,把用户的兴趣爱好和其他用户的兴趣爱好进行一个匹配,当他们的爱好相似度比较高的时候就给双方进行推荐.那么如何进行比较是一个问题,其实我们可以通过余弦匹配算法来对用户的兴趣爱好进行比较,根据计算出来的值来得到一个兴趣爱好相近好友列表,并进行排序. 因为我做的项目是Android端的,所以算法是通过Java实现的,废话不过多说了,下面是算法的实现: pack

  • java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述

    算法是在有限步骤内求解某一问题所使用的一组定义明确的规则.通俗点说,就是计算机解题的过程.在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法.前者是推理实现的算法,后者是操作实现的算法. 一个算法应该具有以下五个重要的特征: 1.有穷性: 一个算法必须保证执行有限步之后结束: 2.确切性: 算法的每一步骤必须有确切的定义: 3.输入:一个算法有0个或多个输入,以刻画运算对象的初始情况: 4.输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果.没有输出的算法是毫无意义的:

  • JAVA实现caesar凯撒加密算法

    复制代码 代码如下: public class Caesar { public static final String SOURCE = "abcdefghijklmnopqrstuvwxyz"; public static final int LEN = SOURCE.length(); /**  * @param args  */ public static void main(String[] args) {     String result = caesarEncryptio

  • java 中模式匹配算法-KMP算法实例详解

    java 中模式匹配算法-KMP算法实例详解 朴素模式匹配算法的最大问题就是太低效了.于是三位前辈发表了一种KMP算法,其中三个字母分别是这三个人名的首字母大写. 简单的说,KMP算法的对于主串的当前位置不回溯.也就是说,如果主串某次比较时,当前下标为i,i之前的字符和子串对应的字符匹配,那么不要再像朴素算法那样将主串的下标回溯,比如主串为"abcababcabcabcabcabc",子串为"abcabx".第一次匹配的时候,主串1,2,3,4,5字符都和子串相应的

  • Java实现的最大匹配分词算法详解

    本文实例讲述了Java实现的最大匹配分词算法.分享给大家供大家参考,具体如下: 全文检索有两个重要的过程: 1分词 2倒排索引 我们先看分词算法 目前对中文分词有两个方向,其中一个是利用概率的思想对文章分词. 也就是如果两个字,一起出现的频率很高的话,我们可以假设这两个字是一个词.这里可以用一个公式衡量:M(A,B)=P(AB)/P(A)P(B),其中 A表示一个字,B表示一个字,P(AB)表示AB相邻出现的概率,P(A)表示A在这篇文章中的频度,P(B)表示B在这篇文章中的频度.用概率分词的好

随机推荐