字符串的排列与组合及八皇后等其他相关问题
来源:互联网 发布:淘宝商城玩具店 编辑:程序博客网 时间:2024/05/21 12:39
1. 字符串全排列(不去重)
【题目】输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
参考:http://www.cnblogs.com/GoAhead/archive/2012/05/30/2526563.html
【分析】采用递归方法:
最外层的循环过程(下面指的是位置交换):
0与0交换abc——内部循环是:1与1交换,输出abc;1与2交换输出acb
0与1交换bac——内部循环是:1与1交换,输出bac;1与2交换输出bca
0与2交换cba——内部循环是:1与1交换,输出cba;1与2交换输出cab
/** * 创建时间:2014年9月7日下午3:29:42 * 项目名称:Test * @author Cao Yanfeng 北京大学 * @since JDK 1.6.0_21 * 类说明: 字符全排列,没有去重 */public classPermutationTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub char[] array={'a','b','c'}; printPermutation(array, 0, array.length); } public static void printPermutation(char[] array,int start,int end) { if (start==end-1) { System.out.println(new String(array)); }else { for (int k = start; k < end; k++) { swap(array, k, start); printPermutation(array, start+1, end); swap(array, k, start); } } } public static void swap(char[] array,int i,int j) { if (array[i]!=array[j]) { array[i]^=array[j]; array[j]^=array[i]; array[i]^=array[j]; } }}
2. 字符串全排列(去重)
【参考】http://blog.csdn.net/hackbuteer1/article/details/7462447
【分析】假设是aac
最外层的循环过程(下面指的是位置交换):
0与0交换aac——内部循环是:1与1交换,输出aac;1与2交换输出aca
0与1交换aac——内部循环是:1与1交换,输出aac;1与2交换输出aca
0与2交换caa——内部循环是:1与1交换,输出caa;1与2交换输出caa
所以要阻断上面红色部分,只要交换条件是:待交换的两个数下标相同(比如上面的原地交换,两个数相等)或者待交换的两个数不相等,也就是说上面的0与0仍能交换,0与1、1与2就不能交换了。
下面程序跟上面相比仅仅加了一行语句:if (k==start||array[k]!=array[start])
/
** * 创建时间:2014年9月7日下午3:29:42 * 项目名称:Test * @author Cao Yanfeng 北京大学 * @since JDK 1.6.0_21 * 类说明: 字符全排列,去重 */public classPermutationTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub char[] array={'a','a','c'}; printPermutation(array, 0, array.length); } public static void printPermutation(char[] array,int start,int end) { if (start==end-1) { System.out.println(new String(array)); }else { for (int k = start; k < end; k++) { if (k==start||array[k]!=array[start]) { swap(array, k, start); printPermutation(array, start+1, end); swap(array, k, start); }else { continue; } } } } public static void swap(char[] array,int i,int j) { if (array[i]!=array[j]) { array[i]^=array[j]; array[j]^=array[i]; array[i]^=array[j]; } } }
3. 字符串的所有组合/字符串的所有子集(不去重)
参考:http://blog.csdn.net/xuyuxin8145/article/details/6637692
【分析】a-b-c的组合可以用递归来实现。假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。
/** * 创建时间:2014年9月7日下午4:42:33 * 项目名称:Test * @author Cao Yanfeng 北京大学 * @since JDK 1.6.0_21 * 类说明: 字符串的所有组合,不去重 */public classCombination { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub char[] array={'a','b','c'}; combination(array); } public static void combination(char[] array) { if (array==null||array.length==0) { return; } ArrayList<Character>result=newArrayList<Character>(); for (int i = 1; i <=array.length; i++) { combination_m(array, 0, i, result); } } public static void combination_m (char[] array,int begin,int m,ArrayList<Character>result){ if (m==0) { System.out.println(result.toString()); return; } if (begin==array.length) { return; } /*选择这个元素*/ result.add(array[begin]); combination_m(array, begin+1, m-1, result); /*不选择这个元素*/ result.remove((Character)array[begin]); combination_m(array, begin+1, m, result); } }
4. 八皇后问题
【问题】在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。
【分析】columnIndex ={0,1,2,3,4,5,6,7}表示的分别是0~7列的行号,所以不会有位于一行的皇后,也不会有位于一列的皇后。八皇后问题,即获得{0,1,2,3,4,5,6,7}所有排列,排除斜对角线情况即可。斜对角的条件是:(i - j == columnIndex[i] - columnIndex[j]) ||( j - i ==columnIndex[i] - columnIndex[j]),例如{0,1,*,*,*,*,*,*}肯定不行,0与1位于对角线。注意,这里为了在递归过程中统计次数,需要传址调用,所以定义了一个Counter类,不能使用int或Integer。
/** * 创建时间:2014年9月7日下午9:03:03 项目名称:Test * * @author Cao Yanfeng Peking University * @since JDK 1.6.0_21 类说明:八皇后问题,即获得{0,1,2,3,4,5,6,7}所有排列,排除斜对角线情况即可 * 注意:{0,1,2,3,4,5,6,7}表示的分别是0~7列的行号,所以不会有位于一行的皇后,也不会有位于一列的皇后。 */public classEightQueenTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub eightQueue(); } public static void eightQueue() { final int queens = 8; int[] columnIndex = new int[queens]; /* 初始化 */ for (int i = 0; i < columnIndex.length; i++) { columnIndex[i] = i; } Countercounter=new Counter(); counter.setCounter(0); /*递归的全排列*/ permutation(columnIndex, 0, columnIndex.length,counter); } public static void permutation(int[] columnIndex, int start, int end,Counter counter) { /*只要当前的指针stat指向了最后一个元素,则递归探底*/ if (start == end - 1) { if (check(columnIndex)) { counter.setCounter(counter.getCounter()+1); System.out.print("第"+counter.getCounter()+"种排列:"); for (int i = 0; i < columnIndex.length; i++) { System.out.print(columnIndex[i]); } System.out.println(); } }else{ for (int k = start; k < end; k++) { swap(columnIndex, k, start); permutation(columnIndex, start + 1, end,counter); swap(columnIndex, k, start); } } } /*查看该数组是否有两个或以上的元素在斜对角线上*/ public static boolean check(int[] columnIndex) { for (int i = 0; i < columnIndex.length; i++) { for (int j = i + 1; j < columnIndex.length; j++) { if (i - j == columnIndex[i] - columnIndex[j] ||j - i == columnIndex[i] - columnIndex[j]) return false; } } return true; } public static void swap(int[] array, int i, int j) { if (array[i] != array[j]) { array[i] ^= array[j]; array[j] ^= array[i]; array[i] ^= array[j]; } } }class Counter{ int counter; public int getCounter() { return counter; } public void setCounter(int counter) { this.counter = counter; } }
5. 数组array中所有元素都只出现一次,给的一个sum,求array的子集和等于sum的所有子集。
参考:http://blog.csdn.net/hackbuteer1/article/details/7462447
【分析】获得array的所有组合,然后判断即可。对上面的主题3“字符串的所有组合/字符串的所有子集合”进行一些修改即可。
/** * 创建时间:2014年9月7日下午9:43:24 项目名称:Test * * @author Cao Yanfeng Peking University * @since JDK 1.6.0_21 类说明:数组的所有子集合中,子集合和等于给定数的集合本质是组合问题 */public classCombinationTest2 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[] array = { 1, 2, 3, 4, 2 }; combination(array, 5); } public static void combination(int[] array, int sum) { if (array == null || array.length == 0) { return; } ArrayList<Integer>result= newArrayList<Integer>(); for (int i = 1; i <= array.length; i++) { combination_m(array, 0, i, result, sum); } } public static void combination_m(int[] array, int begin, int m, ArrayList<Integer>result,intsum){ if (m == 0) { for (Integer integer : result) { sum -= integer; } if (sum == 0) { System.out.println(result.toString()); } return; } if (begin == array.length) { return; } /* 选择这个元素 */ result.add(array[begin]); combination_m(array, begin + 1, m - 1, result, sum); /* 不选择这个元素 */ result.remove((Integer) array[begin]); combination_m(array, begin + 1, m, result, sum); }}
*******************************************************************************
这里遗留了一个问题就是组合有重复的情况,如何去重复。待研究。。。。
- 字符串的排列与组合及八皇后等其他相关问题
- 字符串排列与八皇后问题
- 《编程之法》1.3字符串的全排列,组合,重复排列,八皇后问题
- 字符串的全排列和组合算法(扩展:八皇后问题)
- 字符串数组的全排列到八皇后问题详解
- 字符串数组的全排列到八皇后问题详解
- 八皇后问题和字符串全排列
- 全排列问题、八皇后问题、组合问题的递归解法
- 八皇后问题的全排列解法
- java实现八皇后的排列问题
- 八皇后问题的全排列解法
- 全排列与八皇后的转化
- 有关字符串的全排列,组合 等问题
- 八皇后问题(由字符串排列问题拓展)
- 剑指Offer_面试题28.5_字符串的排列扩展_排列组合_八皇后问题
- 字符串的排列与组合
- 字符串的排列与组合
- 字符串的排列与组合
- 什么原因成就了一位优秀的程序员?
- The Data Scientist's Toolbox
- quartus时序分析文档理解与翻译(4)——创建IO约束
- Holding Bin-Laden Captive!(母函数)
- sqlplus / as sysdba 报错:ora-01031 insufficient privileges
- 字符串的排列与组合及八皇后等其他相关问题
- iOS开发之protocol和delegate
- Codeforces #264 (Div. 2) D. Gargari and Permutations
- echarts高级使用
- Writing GNU Emacs Extensions ch4 要点
- 自考《数据库系统原理》(7)之SQL Server 2000
- POJ 2114 Boatherds
- SCI科研投稿发文宝典
- Log4net自定义信息(变量或属性或字段)存入数据库