思想:针对排列问题,应该将每个位置上可能出现的情况列出来,如有四个不同字符(暂时不考虑有相同情况),那么第一个位置就有四种可能的情况,当第一个位置确定后,第二个位置就只有三种情况,依次类推,最后一个位置只有一种情况,这个对于学过排列组合的人来说,很好理解,关键在于怎样用程序实现呢?
根据上面的分析我们只要挨个把每个位置上出现的字符确定下来,那么这个序列就确定下来了,现在关键是我们针对某个位置出现的情况应该怎样确定呢?比如第一个位置有4种情况,而且每个位置上的字符不相同,那么就可以用整体左移或者右移一位,这样该位置就会出现一种不同的情况,为了要出现四种情况,那么可以用一个循环来控制,直至四种情况都出现。这样该置出现的每种情况也就是确定了这个位置出现的字符。
接下来我们就应该确定第二个位置的字符,第二个位置应该出现三种不同的情况了,也就是从这个位置到最后一个位置上的所有字符作为一个整体向左或右移一位,直至三种情况都出现,也就是有三个位置发生变化,这时会发现这种动作与确定第一个位置使用了相同的方法来确定该位置出现的每种情况,只是少了一位,这就是将一个大的问题转换成一个小一点的问题来解决,那么依次类推,第三个位置的解决办法与第二个位置所使用的方法相同,只是又少移一位(确定的位置不用移动),也就是只有两个位置发生变化,到了最后一个位置了,也就是只有一个位置在变化了,不过怎么变,这个位置上也就只剩下一种情况了,换句话说,这个位置不变了,所有位置上的字符都确定了,那么这时就该输出所有位置上的字符了。
上面这段解释主要是为了引出递归这个思想,我对递归的理解是:对于一个大的问题,可以将它转换成一个较小的问题,然后将这个较小的问题再转换成一个更小的问题来处理,直到最后那个最小的问题得到确定的答案为止,然后再根据这个答案依次回推,而对每个问题都采用相同的方法来处理。下面这个程序的思路是反过来的,也就是先确定最后一个位置出现的情况,然后再确定倒数第二个位置的情况,直到第一个位置确定后输出:
import java.util.Scanner;
public class Permute {
static int count = 0;
public static void main(String[] args) {
System.out.println("please input a String:");
Scanner in = new Scanner(System.in);
String str = in.nextLine();
Permute p = new Permute();
System.out.println(str+"出现的所有排列如下:");
p.permute(str);
System.out.println();
System.out.println("总共有"+count+"种排列");
}
private void permute(String str) {
this.permute(str.toCharArray(), 0, str.length() - 1);
}
//从最后一个位置向前,依次对每个位置上可能出现的字符进行确定(如字符数组是{a,b,c,d},那么最后一个位置可能出现4种情况,确定好第四位置上的字符后,第三个位置可能出现三种情况依次类推)
private void permute(char[] charArray, int low, int high) {
int i;
if (high == low) {//如果是到了第一个位置(low是第一个位置的索引),或者只有一个字符,那么应该输出此字符串
String str = "";
for (i = 0; i < charArray.length; i++) {
str += charArray[i];
}
System.out.print(str+" ");
count++;
} else {
for (int j = low; j <= high; j++) {//将某个位置上可能出现的字符进行遍历(如最后一个位置可能出现high+1种情况)
for (i = low; i < high; i++) {//将第low位置上的字符移到第high位置上
char temp = charArray[i];
charArray[i] = charArray[i + 1];
charArray[i + 1] = temp;
}
permute(charArray, low, high - 1);//当第high位置上的字符确定后,就应该确定第high-1位置上的字符。
}
}
}
}
分享到:
相关推荐
1.6.2. 输入一个字符串,打印出该字符串中字符的所有排列 ........................128 1.6.3. 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数 位于数组的后半部分 ..............
在Golang中实现全排列算法主要是为了解决排列组合问题,特别是在处理字符串或数组时,例如在上述例子中,需要对一组数字进行字典序排序并输出所有可能的排列。全排列算法是找出一个序列中所有可能的排列方式,且每个...
在本例中,所讨论的排序更偏向于全排列生成,即给定一个字符序列,生成该序列中所有可能的字符排列组合。这涉及到组合数学中的排列组合理论,以及如何高效地通过算法实现这些排列的生成。 #### 数据结构应用 - **...
1. 输入两个字符,若这两个字符之差为偶数,则输出它们的后继字符,否则输出它们的前趋字符。 Java知识点:字符操作、条件语句 2. 输入整数a和b,如果a能被b整除,就输出算式和商,否则输出算式、整数商和余数。 ...
1. 如何求一个字符串的所有排列 2. 如何求两个字符串的最长公共子串 3. 如何判断两个字符串是否为换位字符串 4. 如何判断两个字符串的包含关系 5. 如何对由大小写字母组成的字符数组排序 6. 如何消除字符串的内嵌...
首先,计数与期望问题是一类涉及组合数学的复杂问题,常常出现于算法竞赛(如ACM/ICPC、NOI等)以及概率论与数理统计等领域中。该类问题不仅要求参赛者具有扎实的数学基础,还要求有良好的逻辑思维能力和算法设计...
28. 打印字符串中所有字符的排列:涉及到字符串的全排列问题,通常使用递归或交换的方式实现。 29. 数组中出现次数超过一半的数字:这是一个统计问题,可以考虑摩尔投票算法来解决。 30. 找出最小的K个数:可以...
- 字符串操作:利用字符串处理生成不同的三位数组合。 - 循环结构:使用for循环遍历1到4的数字。 - 列表操作:使用列表存储生成的三位数。 - **实现思路**: 1. 创建一个空列表用于存储生成的三位数。 2. 使用...
1. **upper**: 将字符串中的所有字符转换为大写。 2. **lower**: 将字符串中的所有字符转换为小写。 3. **capitalize**: 将字符串的第一个字符转换为大写,其余字符转换为小写。 4. **title**: 将字符串中每个单词的...
任意数字序列“123456”之类,输出它们所有的排列组合** - 可以使用递归算法实现全排列。 - 或者使用迭代法生成所有可能的组合。 **38. 什么是AOP** - AOP(Aspect Oriented Programming)即面向切面编程,用于...
- 使用优先队列(如堆)存储这些树节点,按照权重从小到大排列。 - 每次从队列中取出两个权值最小的节点,合并成一个新的节点,新节点的权值是两个子节点的权值之和,新节点作为子节点加入队列。 - 重复上述步骤...
对于16辆车的情况,我们不需要实际列举所有可能的排列,而是应用组合数学的知识来计算总数。 3. 信号匹配与KMP算法: KMP算法是一种高效的字符串匹配算法,避免了不必要的回溯。在KMP算法中,next数组记录了模式串...
* Predefined character classes 预定义字符序列 * . Any character (may or may not match line terminators) . 任意字符 (也可能不包括行结束符) * \d A digit: [0-9] \d...
计算机应用基础是现代人必备的技能之一,涵盖了计算机硬件、软件、网络等多个方面。下面将对题目中的知识点进行详细解析: 1. 计算机时代的划分:计算机时代主要依据构成元件来划分,从电子管、晶体管、集成电路到...
15. 在Windows中,桌面图标排列类型设置为“自动排列”时,无法将图标拖到桌面任意位置。这是因为Windows操作系统会自动对桌面图标进行排列。 16. 在Word 2003中,可以通过插入手动分页符强制分页。Word是文字处理...
给定先序、中序和后序遍历序列中的任意一个即可 D. 给定一棵二叉树的先序和中序遍历序列 **答案**:B. 给定一棵二叉树的后序和中序遍历序列, D. 给定一棵二叉树的先序和中序遍历序列 **解析**:根据二叉树的遍历...
本题考查的是组合数学中的基本概念之一:二项式系数。具体来说,我们需要找到所有包含偶数个1的8位二进制数的数量。 1. **偶数个1的情况**: - 含有0个1:只有`00000000`一种情况。 - 含有2个1:选择2个位置放1,...
2、实现1所要求的代码后,运行设计好的代码,将以下的几组整数序列建成搜索二叉树,并记录下它们的前序遍历序列和后序遍历序列: a. 1、3、5、7、9; b. 1、13、35、13、27; c. 50、25、78、13、44、...