/* * 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到 * 一个最大的数:65432,一个最小的数23456。 * 求这两个数字的差,得:41976,把这个数字再次重复上述过程(如果不足5位,则前边补0)。 * 如此往复,数字会落入某个循环圈(称为数字黑洞)。 比如,刚才的数字会落入:[82962,75933, 63954, 61974]这个循环圈。 请编写程序,找到5位数所有可能的循环圈,并输出,每个循环圈占1行。 其中5位数全都相同则循环圈为[0],这个可以不考虑。循环圈的输出格式仿照: [82962,75933, 63954, 61974] 其中数字的先后顺序可以不考虑。 */ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class BlackHole { static Set<List<Integer>> sets = new LinkedHashSet<List<Integer>>();// 记录每个 循环圈 static int start = 0; // 记录循环圈的开始位置 // 得到最大的数 public static int max(String s){ char[] c = s.toCharArray(); Arrays.sort(c); StringBuffer sb = new StringBuffer(new String(c)); return Integer.parseInt(sb.reverse().toString()); } // 得到最小的数 public static int min(String s){ char[] c = s.toCharArray(); Arrays.sort(c); return Integer.parseInt(new String(c)); } // 补零 public static String fillZero(String s){ if(s.length()<5) return s; // 如果够五位的话,直接返回原数 StringBuffer sb = new StringBuffer(s); int len = 5 - sb.length(); // 需要补 len 个零 for(int i=0;i<len;i++){ sb.insert(0, "0"); } return sb.toString(); } // 查找是否有循环圈 public static boolean find(int n,List<Integer> lis){ for(int i=0;i<lis.size();i++){ if(n==lis.get(i)){ start = i; // 设置循环圈的开始 return true; } } return false; } // 这个数字的五位是否都一样如:11111,22222,... public static boolean same(int n){ char[] c = (""+n).toCharArray(); char t = c[0]; for(int i=1;i<c.length;i++){ if(t!=c[i]){ return false; } } return true; } // 判断是否在sets元素里重复 public static boolean contain(List<Integer> tt){ boolean flag = false; // 从sets头到尾扫描是是否包含tt元素组 Iterator<List<Integer>> iter = sets.iterator(); while(iter.hasNext()){ if(iter.next().containsAll(tt)){ flag = true; } } return flag; } // 输出循环圈 public static void print(){ Iterator<List<Integer>> iter = sets.iterator(); while(iter.hasNext()){ System.out.println(iter.next()); } } // 进入黑洞测试********* public static void bl(int n,List<Integer> lis){ String tt = fillZero(String.valueOf(n)); int a = max(tt); // 得到最大的数 int b = min(tt); // 得到最小的数 int c = a - b; // 得到五位数 结果 if(find(c,lis)){ // 找到循环圈 lis.add(c); // 把最后一个元素添加进去 List<Integer> temp = new ArrayList(); // 开辟新空间 并copy记录 temp.addAll(lis.subList(start, lis.size()-1)); if(!contain(temp)){ // 去重 sets.add(temp); // 记录一个循环圈 } lis.clear(); // 清空 return ; } lis.add(c); bl(c,lis); // 递归探测 } // 主函数============ public static void main(String[] args){ List<Integer> lis = new ArrayList(); // 保存记录 for(int i=10000;i<99999;i++){ if(!same(i)) //去掉不符合条件的元素:如(11111,22222,...) bl(i,lis); // 进入黑洞测试 } print(); // 输出循环圈 } }
运行结果:
[0] [74943, 62964, 71973, 83952] [63954, 61974, 82962, 75933] [53955, 59994]
作者:hanshileiai 发表于2013-3-31 14:42:27 原文链接
阅读:31 评论:0 查看评论