全排列问题:这是描述数字的全部排列结果的一类问题。有时候经常参杂着一些限制条件。比如12345的全排列,其中34不能连着出现等等。本文以简单的全排列为对象,阐述递归的思想。
递归,要有终止条件,然后向终止条件靠就得到结果了。终止条件可以不止一个。
大致过程如下:
if(终止条件1)
dosomething;
if(终止条件2)
dosomething;
else
去向终止条件递归。
本文以简单的整数全排列问题为demo,示范递归思想。取123456去打印全排列。其中带筛条件的全排列指不能34连续出现的全排列。
全排列代码如下:
package rank;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
public class RankDemo {
/**
* 统计总共的排序方法
*/
private static int totalMehtod;
/**
* 存放带筛选条件的全排列排列结果的map 其中排列结果存放在char[]中
*/
private static Map<Integer, char[]> resultMap = new HashMap<Integer, char[]>();
public static void main(String[] args) {
List<Integer> demoList = new ArrayList<Integer>();
for (int i = 0; i < 6; i++)
demoList.add(i + 1);
//全排列
rank(demoList, new ArrayList<Integer>());
System.out.println("There are " + totalMehtod
+ " method all in records!");
//带筛选条件的全排列
rankComplex(demoList, new ArrayList<Integer>(), resultMap);
printMap(resultMap);
}
/**
* 全排列方法
*
* @param inputList
* @param operationList
*/
public static void rank(List<Integer> inputList, List<Integer> operationList) {
if (inputList.size() == 0)
return;
if (inputList.size() == 1) {
for (Integer value : operationList)
System.out.print(value + " ");
System.out.println(inputList.get(0) + " ");
totalMehtod++;
} else {
for (int i = 0; i < inputList.size(); i++) {
List<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(inputList);
Integer temp = tempList.remove(i);
List<Integer> operationListTemp = new ArrayList<Integer>();
operationListTemp.addAll(operationList);
operationListTemp.add(temp);
rank(tempList, operationListTemp);
}
}
}
/**
* 带有筛选条件的全排列方法
*
* @param inputList
* @param operationList
* @param resultMap
*/
public static void rankComplex(List<Integer> inputList,
List<Integer> operationList, Map<Integer, char[]> resultMap) {
if (inputList.size() == 0)
return;
if (inputList.size() == 1) {
operationList.add(inputList.get(0));
StringBuilder sb = new StringBuilder();
for (Integer value : operationList)
sb.append(value);
String temp = sb.toString();
if (!checkCharArray(temp)) {
totalMehtod++;
resultMap.put(totalMehtod, temp.toCharArray());
}
} else {
for (int i = 0; i < inputList.size(); i++) {
List<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(inputList);
Integer temp = tempList.remove(i);
List<Integer> operationListTemp = new ArrayList<Integer>();
operationListTemp.addAll(operationList);
operationListTemp.add(temp);
rankComplex(tempList, operationListTemp, resultMap);
}
}
}
/**
* 筛选方法
* 如果指定了pattern 那么按照这个pattern进行筛选,否则直接返回true
* 若有多个筛选条件,则都可以指定在这个checkCharArray中
* @param temp
* @return
*/
private static boolean checkCharArray(String temp) {
PatternCompiler pComplier = new Perl5Compiler();
Pattern p = null;
try {
// 这里假定筛选条件为不能为34连续出现
p = pComplier.compile("34");
} catch (MalformedPatternException e) {
e.printStackTrace();
}
if(p == null)
return true;
PatternMatcher matcher = new Perl5Matcher();
return matcher.contains(temp, p);
}
/**
* 打印全排列结果
*
* @param resultMap
*/
public static void printMap(Map<Integer, char[]> resultMap) {
for (Integer key : resultMap.keySet()) {
char[] temp = resultMap.get(key);
for (int i = 0; i < temp.length; i++)
System.out.print(temp[i] + " ");
System.out.println();
}
System.out.println("There are " + resultMap.size()
+ " method all in records!");
}
}
说明:简单全排列只需要找到终止条件 输入待排输入大小为1,然后打印操作链表中的值和这一个最终值就好了,还可以顺便统计处方法总数。而带筛选条件的全排列则只需要将符合条件的结果筛选保存到map中,然后打印map就好了。这里筛选使用了正则表达式,更多关于正则表达式的知识可以查看 apache 的oro项目,具体链接如下:http://jakarta.apache.org/oro/
分享到:
相关推荐
在计算机科学与编程领域中,全排列是一种重要的算法,它被广泛应用于解决多种问题,如组合优化、密码学等。本文将详细介绍两种实现全排列的方法:递归排列和字典序排列,并通过具体的代码示例来加深理解。 #### 一...
递归算法是一种解决问题的方法,它通过将大问题分解为小问题来求解。递归算法的关键在于定义一个基本情况(base case),以及一个或多个递归步骤(recursive steps)。当问题规模缩小到一定程度时,可以直接解决,这...
总结,局部搜索在全排列问题中的应用主要体现在使用递归策略生成排列,但这种方法对于大规模问题效率低下,且处理重复元素时存在问题。对于矩阵最小值问题,全排列提供了所有可能的组合,但计算量随矩阵大小呈指数级...
全排列在笔试面试中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。所以在百度和迅雷的校园招聘以及程序员和软件设计师的考试中都考到了,因此本文对全排列作下...
总结,分治法和回溯法都是解决全排列问题的有效算法。分治法利用递归将问题分解,回溯法则通过试探和回溯寻找所有解。两者在实现细节上有所不同,但都能确保找出所有可能的排列。在实际应用中,根据问题的具体情况和...
在计算机科学与编程领域,全排列问题是一个常见的组合数学问题。全排列是指从给定的n个不同元素中取出m(m≤n)个元素,按照一定的顺序排列起来的方式。递归算法虽然简洁易懂,但在处理大数据量时可能会导致栈溢出等...
本篇介绍的全排列问题是递归应用的一个典型例子,通过这个例子我们可以看到递归如何有效地简化代码,同时也应注意递归可能带来的性能问题。在未来的学习和工作中,合理地使用递归将能帮助我们更好地解决问题。
总结,全排列的C++实现既可以通过递归的回溯策略,也可以通过穷尽所有可能的组合。递归方法简洁,易于理解,但可能会导致大量重复计算。而穷尽法利用内置的`next_permutation`函数,避免了递归带来的开销,但在某些...
全排列算法的非递归实现利用了序列的特性,通过调整找到下一个排列,而递归实现则利用了分治策略,将问题分解为更小的部分进行解决。两种方法各有优势,非递归实现空间效率较高,但可能涉及到较多的局部状态调整;...
总结来说,全排列递归算法是一种利用递归性质解决排列问题的方法。在C#中实现时,需要考虑如何处理重复元素,以避免生成重复的排列。通过递归地将元素插入到合适的位置,并在处理重复元素时加入适当的判断,可以有效...
对于5个数的全排列问题,我们可以设计一个递归函数,将当前已排列的部分和未排列的部分作为参数,每次尝试将未排列的数放到已排列序列的末尾,并递归处理剩余的数。 以下是C语言实现5个数全排列的基本步骤: 1. ...
总结来说,全排列问题是一个典型的组合问题,可以通过递归或回溯策略有效地解决。理解和掌握这些算法不仅有助于解决类似问题,还能够提升对编程和算法设计的理解。对于初学者而言,通过实践和调试这样的程序,可以更...
在计算机科学中,递归算法是一种解决问题的方法,它通过将问题分解为更小的相似子问题来解决复杂问题。本实验旨在帮助学生熟悉Java编程环境,并深入理解递归算法的原理和应用。 **一、实验目标** 1. **熟悉Java...
在编程领域,全排列是一种常见的算法问题,尤其在C#这样的高级编程语言中,它具有广泛的应用场景,例如数据处理、测试用例生成等。全排列是指从n个不同的元素中,按照一定的顺序取出所有可能的排列组合。在这个场景...
总结,全排列算法主要通过递归或迭代实现,利用深度优先搜索或回溯策略。优化方法包括剪枝和记忆化,以减少重复计算和提高效率。对于具体的问题,需要根据实际需求和数据规模选择合适的实现方式。在编程实践中,理解...
总结来说,"QuanPaiLie.rar_全排列"是一个演示如何实现全排列算法的例子,它使用递归方法解决了三个元素的全排列问题。在理解和实现全排列算法的过程中,我们可以学习到递归思想、回溯法以及如何处理排列组合问题的...
递归是一种强大的工具,可以用来解决许多复杂的问题,尤其是那些可以通过分解为更小问题来解决的问题。通过以上分析,我们了解到递归算法的基本结构和实现方法。在实际开发过程中,递归不仅可以简化代码,还可以提高...
总结来说,"数据结构实验-递归"关注的是如何运用递归算法解决数据结构中的实际问题,如全排列和子集生成。掌握这两个概念对于理解和编写高效的计算机程序至关重要,特别是对于那些涉及大量数据操作的领域,如搜索、...
总结来说,MATLAB中的全排列矩阵生成是一个涉及组合优化、递归和非递归算法的问题。通过学习和实践提供的程序,你可以掌握如何在MATLAB环境中高效地生成全排列,这对于提升编程技能和解决相关问题具有重要意义。