A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王广彬 中级黑马   /  2012-7-27 10:04  /  1869 人查看  /  2 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

具体题目是:122345这6个数,打印出它所有可能的组合;要求4不能在第3位,3和5不能相连。
有好多种方法,现在提供一种,看不明白,求详细讲解,谢谢!
package org.qh.demo;
import java.util.ArrayList;
import java.util.List;
public class demo5 {
        public static void main(String[] args) {
                int len = 6;
                int[] numArray = { 1, 2, 2, 3, 4, 5 };
                int[] currentArray = new int[len];
                getNextNumber(0, 1, numArray, currentArray);
        }
        private static void getNextNumber(int preNum, int level, int[] numArray,
                        int[] currentArray) {
                List<Integer> intList = new ArrayList<Integer>();
                for (int i = 0; i < numArray.length; i++) {
                        int currentNum = numArray[i];
                        if (intList.indexOf(Integer.valueOf(currentNum)) > -1)
                                continue;
                        intList.add(currentNum);
                        // 4不能在第3位出现
                        if (level == 3 && currentNum == 4)
                                continue;
                        if (level != 1) {
                                // 3和5不能相连
                                if ((currentNum == 5 && preNum == 3)
                                                || (currentNum == 3 && preNum == 5)) {
                                        continue;
                                }
                        }
                        currentArray[level - 1] = currentNum;
                        int nextLevel = level + 1;
                        if (level == currentArray.length) {
                                OutArray(currentArray);
                                return;
                        } else {
                                getNextNumber(currentNum, nextLevel,
                                                createNewArray(numArray, i), currentArray);
                        }
                }
        }
        private static int[] createNewArray(int[] oldArray, int orderNumber) {
                if (oldArray.length <= 1)
                        return null;
                int newLen = oldArray.length - 1;
                int[] newArray = new int[newLen];
                int newOrderNumber = 0;
                for (int i = 0; i < oldArray.length; i++) {
                        if (i == orderNumber)
                                continue;
                        newArray[newOrderNumber] = oldArray[i];
                        newOrderNumber++;
                }
                return newArray;
        }
        private static void OutArray(int[] array) {
                for (int i = 0; i < array.length; i++) {
                        System.out.print(array[i]);
                }
                System.out.println("");
        }
}

2 个回复

倒序浏览
应该是这样吧!
这个程序的核心是一个递归算法,计算每一位的数据,看结果是否满足条件。
我简单对这个算法的方法进行了注释,你可以看一下:      //  preNum:上一位的值

      //  level:当前位数

      //  numArray:原数组

      //  currentArray:当前正在组合的数组

      private static void getNextNumber(int preNum, int level, int[] numArray,

                        int[] currentArray) {

                // 定义集合,保存已经加入过的数值

                List<Integer> intList = new ArrayList<Integer>();

                // 循环原数组

                for (int i = 0; i < numArray.length; i++) {

                        // 取得一个值

                        int currentNum = numArray[i];

                        // 判断集合中是否出现过这个值,如果出现过,则不使用这个值

                        if (intList.indexOf(Integer.valueOf(currentNum)) > -1)

                                continue;

                        // 将值添加到数组中

                        intList.add(currentNum);



                        // 4不能在第3位出现

                        if (level == 3 && currentNum == 4)

                                continue;

                        if (level != 1) {

                                // 3和5不能相连

                                if ((currentNum == 5 && preNum == 3)

                                                || (currentNum == 3 && preNum == 5)) {

                                        continue;

                                }

                        }



                        // 将通过判断条件的值加入到正组合的数组中

                        currentArray[level - 1] = currentNum;

                        // 计算下一位的位数

                        int nextLevel = level + 1;

                        // 如果当前位数已经达到数组的总位数,则输出结果

                        if (level == currentArray.length) {

                                OutArray(currentArray);

                                return;

                        } else {

                                // 否则继续进行下一位的计算。

                                getNextNumber(currentNum, nextLevel,

                                                createNewArray(numArray, i), currentArray);

                        }

                }

        }

回复 使用道具 举报

回帖奖励 +1

程序的算法是一个深度优先算法(dfs),如果想理解这个程序,你应该先去了解一下深度优先拓展的算法,实现方式很多,可以用栈也可以递归。这个程序的模型是一个六层六叉树,用的是递归,其实理解了dfs通用的算法流程后,这个程序的关键点只是处理每一层节点拓展以及判断父节点的值来决定拓展什么样的子节点,说起来很抽象,其实理解了非常简单
如果你喜欢做这样的题目,建议你多去 poj 和 hdoj 上做一些题目,都是acm算法的题,非常不错,如果有哪些问题,看一下解题报告,讨论都比较多
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马