`
yiding_he
  • 浏览: 446171 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

有条件的全排列

 
阅读更多
题目:对 {1, 2, 2, 3, 4, 5} 进行无重复的全排列,要求 4 不在第三位,且 3,5 不相连。
思路:用 roll() 方法递归构造所有全排列,将每个构造出的排列做判断之后存入结果集。
java 代码
 
  1. import java.util.ArrayList;  
  2.   
  3. /** 
  4.  * 对 {1, 2, 2, 3, 4, 5} 进行无重复的全排列,要求 4 不在第三位,且 3,5 不相连。 
  5.  * 
  6.  * @author <a href="mailto:yiding.he@chinacreator.com">yidinghe</a> 
  7.  */  
  8. public class AllSort {  
  9.   
  10.     static ArrayList<int[]> results = new ArrayList<int[]>();  
  11.   
  12.     public static void main(String[] args) {  
  13.         int[] ints = {122345};  
  14.         roll(ints, 0);  
  15.         for (int[] result : results) {  
  16.             printArr(result);  
  17.         }  
  18.         System.out.println("结果数量:" + results.size());  
  19.     }  
  20.   
  21.     /** 
  22.      * 递归构造全排列假设要排列的数组已经从小到大排好序。 
  23.      * 
  24.      * @param ints    要排列的数组 
  25.      * @param pointer 进行排列的起始位置 
  26.      */  
  27.     private static void roll(int[] ints, int pointer) {  
  28.         if (ints.length < 2) {  
  29.             return;  
  30.         }  
  31.   
  32.         if (pointer == ints.length - 1) {  
  33.             saveResult(ints);  
  34.             return;  
  35.         }  
  36.   
  37.         int[] cloned;  
  38.         for (int i = pointer; i < ints.length; i++) {  
  39.             cloned = ints.clone();  
  40.             int t = cloned[i];  
  41.             cloned[i] = cloned[pointer];  
  42.             cloned[pointer] = t;  
  43.   
  44.             roll(cloned, pointer + 1);  
  45.         }  
  46.     }  
  47.   
  48.     /** 
  49.      * 判断数组是否与现有结果重复且满足条件,如果是则存入结果。 
  50.      * 
  51.      * @param ints 要保存的数组 
  52.      */  
  53.     private static void saveResult(int[] ints) {  
  54.         boolean exists = false;  
  55.   
  56.         for (int[] result : results) {  
  57.             if (same(result, ints)) {  
  58.                 exists = true;  
  59.                 break;  
  60.             }  
  61.         }  
  62.   
  63.         if (!exists && available(ints)) {  
  64.             results.add(ints);  
  65.         }  
  66.     }  
  67.   
  68.     /** 
  69.      * 比较两个数组是否完全相同 
  70.      * 
  71.      * @param a 一个数组 
  72.      * @param b 另一个数组 
  73.      * 
  74.      * @return 如果数组中每个元素都相同,则返回 true。 
  75.      */  
  76.     private static boolean same(int[] a, int[] b) {  
  77.         boolean same = true;  
  78.         for (int i = 0; i < a.length; i++) {  
  79.             if (a[i] != b[i]) {  
  80.                 same = false;  
  81.                 break;  
  82.             }  
  83.         }  
  84.         return same;  
  85.     }  
  86.   
  87.     /** 
  88.      * 输出数组 
  89.      * 
  90.      * @param ints 要输出的数组 
  91.      */  
  92.     private static void printArr(int[] ints) {  
  93.         for (int n : ints) {  
  94.             System.out.print(n + " ");  
  95.         }  
  96.         System.out.println();  
  97.     }  
  98.   
  99.     /** 
  100.      * 检查数组是否符合要求 
  101.      * 
  102.      * @param ints 要检查的数组 
  103.      * 
  104.      * @return 如果 4 在第三位,或者 3 和 5 相连,则返回 false。 
  105.      */  
  106.     private static boolean available(int[] ints) {  
  107.         return ints[2] != 4 && (Math.abs(indexOf(ints, 3) - indexOf(ints, 5)) > 1);  
  108.     }  
  109.   
  110.     /** 
  111.      * 查找指定数字在数组中的位置 
  112.      * 
  113.      * @param ints 指定数组 
  114.      * @param n    指定数字 
  115.      * 
  116.      * @return 指定数字在数组中的位置。如果找不到,则返回 -1。 
  117.      */  
  118.     private static int indexOf(int[] ints, int n) {  
  119.         for (int i = 0; i < ints.length; i++) {  
  120.             if (ints[i] == n) {  
  121.                 return i;  
  122.             }  
  123.         }  
  124.         return -1;  
  125.     }  
  126. }  

输出结果:
java 代码
 
  1. 1 2 2 3 4 5   
  2. 1 2 2 5 4 3   
  3. 1 2 3 2 4 5   
  4. 1 2 3 2 5 4   
  5. 1 2 3 4 2 5   
  6. 1 2 3 4 5 2   
  7. 1 2 5 4 3 2   
  8. ......  
  9. 5 1 2 2 4 3   
  10. 5 1 2 2 3 4   
  11. 5 1 3 2 4 2   
  12. 5 1 3 2 2 4   
  13. 5 1 3 4 2 2   
  14. 结果数量:198  
分享到:
评论

相关推荐

    c++编写的全排列源代码

    例如,对于集合{1,2,3},其全排列有6种:(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)。 ### C++全排列源代码分析 #### 1. **程序结构** 程序首先包含了必要的头文件`"stdafx.h"`和`"iostream.h"`,这...

    全排列-非递归算法

    全排列是一种经典的算法问题,它涉及在给定的有限序列中找出所有可能的元素排列方式。...代码可能涉及到循环、条件判断、数组操作等基本编程概念,通过学习和实践,可以提升对全排列算法的理解和应用能力。

    C#实现解决全排列重复问题

    在编程领域,全排列是一个经典的算法问题,它涉及到如何生成一个序列的所有可能排列方式。...理解并实现全排列算法有助于提升程序员在处理组合与排列问题时的思维能力,是编程技能的重要组成部分。

    易语言源码易语言数字文本的全排列.rar

    例如,对于数字1、2、3,其全排列有123、132、213、231、312、321这六种组合。 在易语言中,实现全排列通常会用到递归或回溯法。递归是一种函数调用自身的技术,而回溯法则是一种在搜索解空间树的过程中,通过不断...

    全排列VisualC++程序

    这种方法直观且易于理解,但可能会有较高的时间和空间复杂度。 另一方面,迭代实现可能使用堆栈或队列等数据结构,通过模拟递归调用的过程。这种实现方式可以有效地控制内存使用,但实现起来相对复杂,需要更深入...

    python练习fibonacci全排列

    全排列问题在解决组合优化问题、搜索问题等领域有广泛应用。在`FullArray.py`文件中,可能包含以下常见的全排列算法: 1. **回溯法**:通过递归和剪枝来生成所有可能的排列,当达到目标条件时返回结果,否则继续...

    全排列C++实现

    全排列递归通常基于回溯思想,即在当前选择的基础上尝试所有可能的选择,如果某个选择不满足条件,则退回一步,尝试其他选择。在C++中,递归函数可以这样设计: ```cpp void permute(vector&lt;int&gt;& nums, int start)...

    全排列算法(分治法求解法和回溯法)

    假设我们有一个长度为n的数组,我们可以选择数组的第一个元素作为排列的首位,然后对剩下的n-1个元素进行全排列。这样,我们得到了所有可能的首位,与剩下的元素的全排列组合起来,就得到了全部的n位排列。 具体...

    全排列的算法(有重复数据)

    n个有重复元素全排列:无重复的全排列为序列头元素与所有元素进行交换共n种情况,每种情况的后n-1位元素构成新的序列。 重复以上过程。因为有重复元素,想要序列不重复:(1)需要保证序列头元素与其余元素一次交换...

    整数分拆以及等差数列多重约束条件下全排列的生成法

    在数学上,整数分拆问题已经有了相当深入的研究,但对于同时考虑等差数列约束条件下的全排列生成方法,还需要进一步的探索。 等差数列是数学中的基本序列,其任意相邻两项之差是一个常数,称为公差。在全排列中引入...

    QuanPaiLie.rar_全排列

    全排列问题的解决不仅有助于理解递归和回溯算法,还能锻炼编程思维。在实际应用中,全排列可以用于解决诸如日程安排、密码生成、组合优化等问题。在解决全排列问题时,需要注意优化算法以避免重复计算和提高效率,...

    qpl.rar_全排列

    递归函数的基线条件是当需要排列的元素只剩下一个时,输出这个排列。 3. 在递归过程中,对每一个尚未固定的元素,尝试将其与后面未排列的元素交换,然后对剩余的元素继续进行全排列。 4. 当一个排列生成后,恢复原...

    复式全排列.zip

    而复式全排列,也称为多重排列或部分排列,是全排列的一个扩展,它允许重复元素的出现,并且对重复元素有一定的限制。 在计算机编程中,复式全排列常常用于解决需要考虑重复元素的排列问题,比如生成所有可能的密码...

    quanpailie.zip_输入全排列

    全排列算法虽然在n较大时会面临指数级的时间复杂度,但在n较小或者有限制条件的场景下,仍然是非常实用的工具。在编程实践中,应结合具体问题优化算法,如使用剪枝等技术减少无效计算,提高效率。

    n个数的全排列

    全排列在许多实际问题中都有应用,如密码学、计算机图形学(如图像旋转)、软件测试(生成各种输入组合以覆盖所有可能的测试情况)以及组合优化问题(如旅行商问题的解空间搜索)等。理解并熟练掌握全排列的生成算法...

    全排列算法

    5. **优化和变种**:如使用迭代而非递归,或者在特定条件下提前剪枝以减少计算量。 在实际应用中,全排列算法常用于密码学、组合优化、搜索问题等领域。通过这个课程设计,学生不仅能掌握全排列的实现,还能提升...

    全排列算法设计分析.ppt

    递归版本的全排列算法通常会设定一个基础条件,当n等于1时直接返回当前元素,然后在其他情况下,遍历序列的每个元素,将当前元素与第一个元素交换,并对剩下的n-1个元素进行递归调用,以生成新的排列。 另一种方法...

    Python字符串的全排列算法实例详解

    3. **递归终止条件**:递归函数需要有一个明确的终止条件,即当字符串长度为1时,直接返回该字符串即可。 4. **递归逻辑**:对于每个字符,将其与后面的每个字符进行交换,并对剩余部分进行递归处理。 5. **去重处理...

    使用C语言解决字符串全排列问题

    必须有可达到的终止条件,否则程序陷入死循环 子问题在规模上比原问题小 子问题可通过再次递归调用求解 子问题的解应能组合成整个问题的解 对于字符串的排列问题: 如果能生成n-1个元素的全排列,就能生成n个...

    蓝桥杯Python模拟赛题之数学问题全排列.zip

    在蓝桥杯的Python模拟赛题中,可能会遇到的具体问题是要求求解特定条件下的全排列,比如限制某些元素不能相邻,或者需要满足特定的顺序关系等。为了解决这类问题,我们可能需要结合其他算法或技巧,例如回溯法、深度...

Global site tag (gtag.js) - Google Analytics