1. 程式人生 > >用1、2、2、3、4、5這六個數字,打印出所有不同的排列

用1、2、2、3、4、5這六個數字,打印出所有不同的排列

轉換成整型值,用累加的方法遍歷從最小到最大的所有數值,輸出包含指定字元及其指定個數的數字。
由於要遍歷更多的數字,所以耗時較大。

public class Main {
    public static int count = 0;
    private static String[] mustExistNumber=new String[]{"1","2","2","3","4","5"};
    public static void main(String[] args) {
        String s = "122345";
        for(int i=122345
;i<=543221;i++){ if(validateNum(i+"")){ System.out.println(i); count++; } } System.out.println(count); } public static boolean validateNum(String num){ for(String number:mustExistNumber){ if(num.indexOf(number)<0
){ return false; } if(num.indexOf("2")==num.lastIndexOf("2")){ return false; } } return true; } }

遞迴:

遍歷抽取每個字母作為字首,然後從剩下的字元中抽取字母與其組合。

    public static int count=0;
    public static void main(String[] args) {
        String s="122345"
; Pailie(s,""); System.out.println(count); } static void Pailie(String s,String p) { if(s.length()<1){ System.out.println(p); count++; }else{ int index[]=new int[s.length()]; for(int i=0;i<s.length();i++){ index[i]=s.indexOf(s.charAt(i)); } for(int i=0;i<s.length();i++){ if(i==index[i]){//保證相同字元中的第一次呼叫 Pailie(s.substring(1),p+s.substring(0, 1)); } s=s.substring(1)+s.substring(0,1);//迴圈移位,使每次都是在起始位置選擇第一個 } } }

第二種遞迴方法,與前面的不同點在於,使用了List代替String來操作資料,並使用LinkedList來提取並移除每個元素,避免了字串拼接操作。使用StringBuilder儲存前面已經出現的字元,避免遞迴後面重複的字元。

public static int count=0;
    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();    //獲取開始時間
//        String[] array=new String[]{"1","2","2","3","4","5"};
//        listAll(Arrays.asList(array),"");
        String s = "122345";
        listAll(Arrays.asList(s.split("")),"");
        System.out.println(count);
        long endTime = System.currentTimeMillis();    //獲取結束時間
        System.out.println("程式執行時間:" + (endTime - startTime) + "ms");    //輸出程式執行時間
    }

    private static void listAll(List<String> candidate, String prefix) {
        if(candidate.isEmpty()) {
            System.out.println(prefix);
            count++;
        }else {
            StringBuilder sb=new StringBuilder();//記錄前面已經出現的字元
            for (int i = 0; i < candidate.size(); i++) {
                if(sb.indexOf(candidate.get(i))!=-1){//如果是重複字元就不遞迴
                    continue;
                }
                List temp = new LinkedList(candidate);//為了方便提取後刪除每個元素
                listAll(temp, prefix + temp.remove(i));
                sb.append(candidate.get(i));
            }
        }
    }

1、2、2、3、4、5這六個數字,用java寫一個main函式,打印出所有不同的排列, 如:512234、412345等.
要求:”4”不能在第三位,”3”與”5”不能相連。

方法一:


    private static String[] mustExistNumber = new String[] { "1", "2", "2", "3", "4", "5" };

    private static boolean isValidNumber(String str) {
        // 檢查是否包含12345這五個數,不包含返回false
        for (String number : mustExistNumber) {
            if (str.indexOf(number) < 0)
                return false;
        }
        // 檢查是否有兩個2,只有一個返回false
        if (str.lastIndexOf("2") == str.indexOf("2")) {
            return false;
        }
        // 檢查4在不在第三位,是返回false
        if (str.charAt(2) == '4') {
            return false;
        }
        // 檢查是否存在35在一起,有返回false
        if (str.indexOf("35") >= 0 || str.indexOf("53") >= 0) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        int count=0;
        for (int i = 122345; i <=543221; i++) {
            if (isValidNumber(String.valueOf(i))) {
                System.out.println(i);
                count++;
            }
        }
        System.out.println(count);
    }

根據上道題修改,輸出前增加判斷

    public static int count=0;
    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();    //獲取開始時間
//        String[] array=new String[]{"1","2","2","3","4","5"};
//        listAll(Arrays.asList(array),"");
        String s = "122345";
        listAll(Arrays.asList(s.split("")),"");
        System.out.println(count);
        long endTime = System.currentTimeMillis();    //獲取結束時間
        System.out.println("程式執行時間:" + (endTime - startTime) + "ms");    //輸出程式執行時間
    }

    private static void listAll(List<String> candidate, String prefix) {
        if(candidate.isEmpty()) {
            if(prefix.charAt(2)=='4'||prefix.contains("35")||prefix.contains("53")){
                return;
            }
            System.out.println(prefix);
            count++;
        }else {
            StringBuilder sb=new StringBuilder();//記錄前面已經出現的字元
            for (int i = 0; i < candidate.size(); i++) {
                if(sb.indexOf(candidate.get(i))!=-1){//如果是重複字元就不遞迴
                    continue;
                }
                List temp = new LinkedList(candidate);//為了方便提取後刪除每個元素
                listAll(temp, prefix + temp.remove(i));
                sb.append(candidate.get(i));
            }
        }
    }

方法三:

    public static Set<String> set = new TreeSet<String>();

    public static void perm(char[] n, int beg, int end) {//最後一位交換與後面每位交換,對新串遞迴
        if (beg == end) {
            addNumber(String.valueOf(n));
        } else {
            for (int i = beg; i <= end; ++i) {
                swap(n, beg, i);
                perm(n, beg + 1, end);
                swap(n, beg, i);
            }
        }
    }

    public static void swap(char[] n, int x, int y) {//交換
        if (x == y || n[x] == n[y]) {
            return;
        }
        char temp = n[x];
        n[x] = n[y];
        n[y] = temp;
    }

    public static void addNumber(String str) {//如果第三位是4,或者3、5相連,不新增到集合中
        if (str.charAt(2) == '4' || str.contains("35") || str.contains("53")) {
            return;
        }
        set.add(str);
    }

    public static void main(String args[]) {
        char[] number = new char[] { '1', '2', '2', '3', '4', '5' };
        perm(number, 0, number.length - 1);
        System.out.println(set.size());
        int cols = 10;
        for (String s : set) {
            System.out.print(s + " ");
            if (cols-- == 1) {
                System.out.println();
                cols = 10;
            }
        }
    }