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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. package com.itheima;

  2. import java.util.Scanner;

  3. public class Test7 {

  4.         /**
  5.          * 7、编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如: 原始字符串是"abc",打印得到下列所有组合情况: "a" "b"
  6.          * "c" "ab" "bc" "ca" "ba" "cb" "ac" "abc" "acb" "bac" "bca" "cab" "cba"
  7.          *
  8.          * 思路:1,将字符串拆分为单个字符 2,使用递归算法进行组合
  9.          *
  10.          */
  11.         public static void main(String[] args) {
  12.                 // System.out.println("请输入所要转换的字母或单词!");
  13.                 // //定义并初始化键盘读入语句
  14.                 // Scanner sc = new Scanner(System.in);
  15.                 // //声明字符串接收从键盘读取的字符串
  16.                 // String str = sc.nextLine();
  17.                 print("sah");
  18.         }

  19.         public static void print(String str) {
  20.                 int x = str.length();
  21.                 String[] ch1 = new String[x];
  22.                 String[] ch2 = new String[x];
  23.                 for (int i = 0; i < str.length(); i++) {
  24.                         ch1[i] = str.substring(i, i + 1);
  25.                         ch2[i] = str.substring(i, i + 1);
  26.                 }
  27.                 myout(ch1, ch2);
  28.         }

  29.         public static void myout(String[] ch1, String[] ch2) {
  30.                 StringBuffer sbf = new StringBuffer();
  31.                 String[] ch3 = null;
  32.                 int k = 1;
  33.                 k++;
  34.                 for (int i = 0; i < ch1.length; i++) {
  35.                         for (int j = 0; j < ch2.length; j++) {
  36.                                 // System.out.println(ch2.length);
  37.                                 if (!ch1[i].contains(ch2[j])) {
  38.                                         String s = ch1[i] + ch2[j];
  39.                                         sbf.append(s);
  40.                                         sbf.append("*");
  41.                                 }
  42.                         }
  43.                 }
  44.                 // 切割sbf
  45.                 String s = sbf.toString();
  46.                 System.out.println(s);
  47.                 String regex = "[*]";
  48.                 ch3 = s.split(regex);
  49.                 for (String string : ch3) {
  50.                         System.out.println(string);
  51.                 }
  52.                 if (k <= ch1.length) {
  53.                         myout(ch1, ch3);
  54.                 }
  55.         }
  56. }
复制代码






下面是解决方案:
  1. package com.itheima;

  2. import java.util.Scanner;

  3. public class Test7 {

  4.         /**
  5.          * 7、编程列出一个字符串的全字符组合情况,原始字符串中没有重复字符,例如: 原始字符串是"abc",打印得到下列所有组合情况: "a" "b"
  6.          * "c" "ab" "bc" "ca" "ba" "cb" "ac" "abc" "acb" "bac" "bca" "cab" "cba"
  7.          *
  8.          * 思路:1,将字符串拆分为单个字符 2,使用递归算法进行组合
  9.          *                
  10.          */
  11.         //定义静态变量k 控制递归次数
  12.         static int k=1;
  13.         //自定义异常,用于跳出递归的死循环
  14.         @SuppressWarnings("serial")
  15.         static class StopException extends RuntimeException{}
  16.         public static void main(String[] args) {
  17.                  System.out.println("请输入所要转换的字母或单词!");
  18.                  //定义并初始化键盘读入语句
  19.                  Scanner sc = new Scanner(System.in);
  20.                  //声明字符串接收从键盘读取的字符串
  21.                  String str = sc.nextLine();
  22.                  //捕获自定义异常,用于跳出递归
  23.                 try {
  24.                         printfirst(str);
  25.                 } catch (StopException e) {
  26.                 }
  27.         }

  28.         public static void printfirst(String str) {
  29.                 //定义两个字符串数组并获取所输入字符串的单个字符加入到数组中
  30.                 //用于对双字符串的匹配合成。
  31.                 int x = str.length();
  32.                 String[] ch1 = new String[x];
  33.                 String[] ch2 = new String[x];
  34.                 for (int i = 0; i < str.length(); i++) {
  35.                         ch1[i] = str.substring(i, i + 1);
  36.                         ch2[i] = str.substring(i, i + 1);
  37.                 }
  38.                 //遍历数组输出题目要求的单个字符
  39.                 for (String string1 : ch1) {
  40.                         System.out.print(string1+" ");
  41.                 }
  42.                 //调用匹配的递归函数,并将数组ch1 ch2传进去
  43.                 myout(ch1, ch2);
  44.         }
  45.         //定义函数,该函数用于将得到的任意两个字符数组,匹配出不重复的任意组合并输出。
  46.         public static void myout(String[] ch1, String[] ch2) {
  47.                 //定义StringBuffer 用于储存组合后的字符。
  48.                 StringBuffer sbf = new StringBuffer();
  49.                 //定义字符串数组用于储存组合后的字符串
  50.                 String[] ch3 = null;
  51.                 //对递归循环次数控制的变量k+1
  52.                 k++;
  53.                 //外层循环遍历匹配字符
  54.                 for (int i = 0; i < ch1.length; i++) {
  55.                         //内层循环遍历匹配字符
  56.                         for (int j = 0; j < ch2.length; j++) {
  57.                                 // System.out.println(ch2.length);
  58.                                 //对传入的两个字符串数组进行匹配,被组合的字符串数组
  59.                                 //中的数据不包含原始字符则进行组合。
  60.                                 if (!(ch2[j].contains(ch1[i]))) {
  61.                                         //定义新的字符串接收组合后的字符串
  62.                                         String s = ch1[i] + ch2[j];
  63.                                         //将字符串和*加入sbf
  64.                                         sbf.append(s);
  65.                                         sbf.append("*");
  66.                                 }
  67.                         }
  68.                 }
  69.                 // 将sbf转化为字符串方便进行切割操作
  70.                 String s = sbf.toString();
  71.                 //System.out.println(s);
  72.                 //定义正则表达式并切割字符串加入字符数组中
  73.                 String regex = "[*]";
  74.                 ch3 = s.split(regex);
  75.                 //遍历输出字符串数组
  76.                 for (String string : ch3) {
  77.                         System.out.print(string+" ");
  78.                 }
  79.                 //判断循环次数,并抛出自定义异常以跳出递归
  80.                 if (k>=ch1.length){
  81.                         //System.out.println(k);
  82.                         throw new StopException();
  83.                 }
  84.                 //递归
  85.                 myout(ch1, ch3);
  86.         }
  87.        
  88. }
复制代码




使用抛出自定义异常解决递归死循环问题。

3 个回复

倒序浏览
前面代码陷入死循环
回复 使用道具 举报
本帖最后由 LoveMyself 于 2015-5-18 10:58 编辑

楼主递归算法写的很赞,亮点:能想到通过设置静态变量k恰到好处的与自定义 RnutimeException  相结合,来准确的结束循环;
                                                 其中的小细节:1、StringBuffer 中的append  没必要写成:append(s);append("*");
                                                                              用append(s + "*");就可以搞定了
                                                                        2、String regex = "
  • ";ch3 = s.split(regex); 感觉没必要呀换成ch3 = s.split("*"); 感觉就可以了呀


  • 回复 使用道具 举报
    真是学习了,我去琢磨琢磨了,谢谢分享
    回复 使用道具 举报
    您需要登录后才可以回帖 登录 | 加入黑马