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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 中国移动 黑马帝   /  2012-7-20 00:48  /  1836 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

问题:用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连。

解答的大牛,希望给出思路和给出代码的注释谢谢


点评

鼓励算法问题  发表于 2012-7-20 02:10

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

8 个回复

倒序浏览
自己抢板凳,在线等
回复 使用道具 举报
谁自己解答此题目,奖励3分技术分
回复 使用道具 举报
  1. static int[] bits = new int[] { 1, 2, 3, 4, 5 };
  2. /**
  3. * @参数
  4. */
  5. public static void main(String[] args) {
  6. sort("", bits);
  7. }

  8. private static void sort(String prefix, int[] a) {
  9. if (a.length == 1) {
  10. System.out.println(prefix + a[0]);
  11. }

  12. for (int i = 0; i < a.length; i++) {
  13. sort(prefix + a[i], copy(a, i));
  14. }
  15. }

  16. private static int[] copy(int[] a,int index){
  17. int[] b = new int[a.length-1];
  18. System.arraycopy(a, 0, b, 0, index);
  19. System.arraycopy(a, index+1, b, index, a.length-index-1);
  20. return b;
  21. }

复制代码
基本思路:
1 把问题归结为图结构的遍历问题。实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。
2 显然这个结果集还未达到题目的要求。从以下几个方面考虑:
  1. 3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。
  2. 不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果
  3. 4不能在第三位: 仍旧在结果集中去除满足此条件的结果。
采用二维数组定义图结构,最后的代码是:
  1. import java.util.Iterator;
  2. import java.util.TreeSet;

  3. public class TestQuestion {

  4. private String[] b = new String[]{"1", "2", "2", "3", "4", "5"};
  5. private int n = b.length;
  6. private boolean[] visited = new boolean[n];
  7. private int[][] a = new int[n][n];
  8. private String result = "";
  9. private TreeSet set = new TreeSet();

  10. public static void main(String[] args) {
  11. new TestQuestion().start();
  12. }

  13. private void start() {

  14. // 初始化map a[][]
  15. for (int i = 0; i < n; i++) {
  16. for (int j = 0; j < n; j++) {
  17. if (i == j) {
  18. a[i][j] = 0;
  19. } else {
  20. a[i][j] = 1;
  21. }
  22. }
  23. }

  24. //3和5不能相连
  25. a[3][5] = 0;
  26. a[5][3] = 0;

  27. for (int i = 0; i < n; i++) {
  28. this.depthFirstSearch(i);
  29. }

  30. // 打印结果
  31. Iterator it = set.iterator();
  32. while (it.hasNext()) {
  33. String string = (String) it.next();
  34. //“4”不能在第三的位置
  35. if (string.indexOf("4") != 2) {
  36. System.out.println(string);
  37. }
  38. }
  39. }

  40. private void depthFirstSearch(int startIndex) {
  41. visited[startIndex] = true;
  42. result = result + b[startIndex];
  43. if (result.length() == n) {
  44. //过滤重复的值
  45. set.add(result);
  46. }
  47. for(int j = 0; j < n; j++) {
  48. if (a[startIndex][j] == 1 && visited[j] == false) {
  49. depthFirstSearch(j);
  50. } else {
  51. continue;
  52. }
  53. }

  54. // 恢复
  55. result = result.substring(0, result.length() -1);
  56. visited[startIndex] = false;
  57. }
  58. }
复制代码

点评

滔哥 我想给你加5分....  发表于 2012-7-20 06:33
回复 使用道具 举报
我有个想法,就是把随机生成的序列放到一个String类型的ArrayList或者数组中,然后遍历集合或者数组,取出的每个字符串进行正则表达式的判断。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1 应该可以实现

查看全部评分

回复 使用道具 举报
王宝康 发表于 2012-7-20 02:01
我有个想法,就是把随机生成的序列放到一个String类型的ArrayList或者数组中,然后遍历集合或者数组,取出 ...


就凭这一分,我一定要做出来!这是被认同的喜悦,哈哈...
回复 使用道具 举报
滔哥 发表于 2012-7-20 01:40
基本思路:
1 把问题归结为图结构的遍历问题。实际上6个数字就是六个结点,把六个结点连接成无向连通图,对 ...

{:3_47:}滔哥V5 霸气测漏啊
回复 使用道具 举报
王艺霖 发表于 2012-7-20 01:35
最简单的就是
                   用外部变量接
1:首先要考虑他们是怎么组合排列的

{:3_46:}羡慕嫉妒恨,你要谢谢我啊,你因为我得了3分啊!算法V5
回复 使用道具 举报
韦念欣 黑马帝 2012-7-20 02:26:09
9#
本帖最后由 韦念欣 于 2012-7-20 02:28 编辑


这个我的代码!
  1. /*
  2. 问题:        用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,
  3.                 如:512234、212345等,要求:"4"不能在第三位,"3"与"5"不能相连。
  4. */
  5. public class Demo
  6. {
  7.         public static long count = 0;
  8.         public static void main(String[] args){
  9.                 final String number = "122345";                        // 自定义N个数字(可以是N个任意字符)
  10.                 arrange(number,                                                 // 调用arrange方法递归遍历所有排列
  11.                                 new char[number.length()],
  12.                                 new boolean[number.length()],
  13.                                 0);
  14.                 System.out.println("符合要求的数据共有:"+ count +"个.");
  15.         }

  16.         // 方法:递归遍历所有排列
  17.         // 参数:number        需要排列的字符
  18.         //                 tmp         临时结果数组
  19.         //                 used       每个字符的使用标识(标记是否已经使用)
  20.         //                 n              正在遍历的第n个数据
  21.         public static void arrange(final String number, char[] tmp, boolean[] used, int n){
  22.                
  23.                 // 递归出口:当得到一个与number长度相同的数据
  24.                 if (n == number.length()){
  25.                         String result = new String(tmp);                   // 将char数组转换为String

  26.                         // 判断条件:"4"不能在第三位,"3"与"5"不能相连
  27.                         if (tmp[2] != '4' && !result.contains("35") && !result.contains("53")){
  28.                                 System.out.println(result);
  29.                                 ++count;                                                // 统计符合要求的结果
  30.                         }
  31.                         return;
  32.                 }

  33.                 // 递归排列
  34.                 for (int i=0; i<number.length(); i++){
  35.                         // 若当前数据为被使用
  36.                         if (!used[i]){
  37.                                 used[i] = true;                                        // 使用当前数据
  38.                                 tmp[n] = number.charAt(i);                  // 将数据填入临时结果数组中
  39.                                 arrange(number, tmp, used ,n+1);       // 递归遍历下一位数据
  40.                                 used[i] = false;                                       // 已经使用完当前数据
  41.                         }
  42.                 }
  43.         }
  44. }
复制代码

点评

老毕的学子啊,来就甩文档注释,甩思路,哈哈  发表于 2012-7-20 02:29

评分

参与人数 1技术分 +3 收起 理由
滔哥 + 3

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马