- 浏览: 53932 次
- 性别:
- 来自: 北京
文章分类
最新评论
无重复数的组合问题
就是集合的所有非空子集
比如 {1,2,3}
的组合结果是
{1},{2},{3}
{1,2}{1,3}{2,3}
{1,2,3}
组合跟关键字的排列顺序无关
利用全排列算法求解
全排列算法可以求出集合所有的子集排列
所以 组合就是全排列的一个子集
1
2
3
12
13
21
23
31
32
123
132
213
231
312
321
一共是15个
取其中的长度为分别为1,2,3的递增序列就ok了
长度为1的: 1 2 3
长度为2的: 12 13 23
长度为3的: 123
因为组合是无序的,所以其他的舍弃
全排列参考
http://viking-liu.iteye.com/admin/blogs/1198952
一般的算法书上都有
上面这个算法的问题是求了在判断已排的序列是有有序时,从头开始,其实没有这个必要
因为每次递归都在判断,只要判断最后序列两个是否有序就ok了。
具体优化如下:
上面的问题解决了判断序列是否有序时,减少比较次数。
但是整个全排列的交换次数很多,而且很多是没有意义的交换,
那么什么样的交换没有意义呢?
比如
3 21
3已经排好了,那么排21,2和1的交换就是没有意义的
因为组合只输出升序,无论 321 还是 312 最终都只有一个 3输出
所以要避免这种没有意义的交换
接着优化
可以在每种方法中加入交换计数器c 计算组合的交换次数
最后一种的交换次数比前面两中方法的交换次数少很多
如果不是很理解,应该先理解全排列的算法
上面方法都是基于全排列算法改进的
求组合更好的方法。。。。
就是集合的所有非空子集
比如 {1,2,3}
的组合结果是
{1},{2},{3}
{1,2}{1,3}{2,3}
{1,2,3}
组合跟关键字的排列顺序无关
利用全排列算法求解
全排列算法可以求出集合所有的子集排列
所以 组合就是全排列的一个子集
1
2
3
12
13
21
23
31
32
123
132
213
231
312
321
一共是15个
取其中的长度为分别为1,2,3的递增序列就ok了
长度为1的: 1 2 3
长度为2的: 12 13 23
长度为3的: 123
因为组合是无序的,所以其他的舍弃
全排列参考
http://viking-liu.iteye.com/admin/blogs/1198952
一般的算法书上都有
package com.viking.divide; public class Combination { public static void main(String[] args) { int[] a = { 1, 2, 3 ,4}; System.out.println(perm(a, 0)); } public static int perm(int[] a, int begin) { int count = 0; String path = ""; for (int i = 0; i < begin - 1; i++) { if (a[i] > a[i + 1]) { return 0; } path += a[i] + " "; } if (begin > 0) { // 输出有序的子集 就是组合的所有结果 System.out.println(path + a[begin - 1]); count = 1; } if (begin == a.length) { return count; } for (int i = begin; i < a.length; i++) { swap(a, begin, i); count += perm(a, begin + 1); swap(a, begin, i); } return count; } public static void swap(int[] a, int begin, int end) { int temp = a[begin]; a[begin] = a[end]; a[end] = temp; } }
上面这个算法的问题是求了在判断已排的序列是有有序时,从头开始,其实没有这个必要
因为每次递归都在判断,只要判断最后序列两个是否有序就ok了。
具体优化如下:
package com.viking.divide; public class Combination { public static void main(String[] args) { int[] a = { 5, 2, 3, 4 }; System.out.println(perm(a, 0)); } public static int perm(int[] a, int begin) { int count = 0; if (begin > 0) { if (begin > 1 && a[begin - 1] < a[begin - 2]) { //已排好数列无序 return 0; } for (int i = 0; i < begin; i++) { System.out.print(a[i] + " "); } System.out.println(); count = 1; } for (int i = begin; i < a.length; i++) { swap(a, begin, i); count += perm(a, begin + 1); swap(a, begin, i); } return count; } public static void swap(int[] a, int begin, int end) { int temp = a[begin]; a[begin] = a[end]; a[end] = temp; } }
上面的问题解决了判断序列是否有序时,减少比较次数。
但是整个全排列的交换次数很多,而且很多是没有意义的交换,
那么什么样的交换没有意义呢?
比如
3 21
3已经排好了,那么排21,2和1的交换就是没有意义的
因为组合只输出升序,无论 321 还是 312 最终都只有一个 3输出
所以要避免这种没有意义的交换
接着优化
package com.viking.divide; public class Combination2 { public static void main(String[] args) { int[] a = { 4, 2, 3, 1 }; System.out.println(perm(a, 0)); } public static int c=0; public static int perm(int[] a, int begin) { int count = 0; if (begin > 0) { for (int i = 0; i < begin; i++) { System.out.print(a[i] + " "); } System.out.println(); count = 1; } for (int i = begin; i < a.length; i++) { if (begin == 0 || a[begin - 1] < a[i]) { // 组合数没有顺序,所以用从小到大进行输出 // 如果交换后不是升序,那么就不用交换,这样可以减少没有必要的交换 swap(a, begin, i); count += perm(a, begin + 1); swap(a, begin, i); } } return count; } public static void swap(int[] a, int begin, int end) { if (begin != end) { int temp = a[begin]; a[begin] = a[end]; a[end] = temp; } } }
可以在每种方法中加入交换计数器c 计算组合的交换次数
最后一种的交换次数比前面两中方法的交换次数少很多
如果不是很理解,应该先理解全排列的算法
上面方法都是基于全排列算法改进的
求组合更好的方法。。。。
发表评论
-
查找任意两个节点的公共父节点
2011-11-04 00:42 3554基本思路是对需要查找的节点赋权值为1,其它节点权值为0.那么只 ... -
树中任意两个节点之间的距离
2011-11-04 00:28 9624树中任意两个节点之间的距离是指,从一个节点到另一个几点之间的一 ... -
用5,7,12加减运算,求最少步数得到任意数n
2011-11-03 23:59 1269package www.viking.com.algori ... -
线段重合问题
2011-11-01 13:21 2977问题:y=ax+b; 有很多线段{x0,y0,x1,y1}{ ... -
区间覆盖问题
2011-11-01 13:00 1650问题: 有很多区间,比如[1.1,3.4] [1,3] [-1 ... -
数组循环移位
2011-10-31 22:09 1442比如1 2 3 4 5 循环移位1位 ... -
最大子矩阵的和
2011-10-25 15:30 764package www.viking.com.algo ... -
最大字段和
2011-10-25 14:43 925package www.viking.com.algo ... -
有重复数的全排列
2011-10-21 18:34 8126有重复数的全排列和全排列的算法是一样的 只不过要去掉重复的序列 ... -
有重复数的组合
2011-10-21 18:33 931package com.viking.divide; ... -
m n 全排列
2011-10-21 08:54 850n个字符中长度为m的全排列 public class MN ... -
子集的全排列
2011-10-21 08:51 865比如 123 1 2 3 12 21 13 31 23 32 ... -
google笔试题 人民币问题
2011-10-20 23:57 774方法一:递归方法 对 charge[]={1,5,10,20, ... -
查找无向图中的环
2011-10-19 23:51 1922static int[][] M = { { 0 ... -
无重复数的全排列问题
2011-10-18 09:51 911采用分治思想,很多书都有。。。 这里只是引用一下,因为有很几 ... -
爬台阶问题
2011-10-18 07:57 946package com.viking.dynamic; ... -
查找中间数
2011-10-18 00:21 758package com.viking.divide; ... -
整数的因子分解
2011-10-17 23:21 955package com.viking.divide; ...
相关推荐
在C#编程中,生成不重复的字母数字组合是一项常见的任务,特别是在密码生成、验证码创建或者唯一标识符的生产场景中。本篇文章将详细讲解如何使用C#来生成指定长度的不重复字母数字组合,包括两位及任意N位的情况。 ...
这可能是为了实现某种特定的验证或者筛选机制,比如检查生成的数字是否满足某个条件(比如能被某个数整除)或者计算特定组合的总和。 易语言的源码文件中,可能会包含以下几个关键部分: 1. 数字集合定义:初始化0-...
在C#编程中,生成不重复的字母数字组合是一个常见的需求,这可能涉及到密码生成、唯一标识符创建或数据加密等多个领域。在这种情况下,我们通常会利用C#的内置类和方法来实现这一功能。标题提到的是“C#生成不重复...
通过运行上述代码,我们可以得到所有的不同三位数组合: - 123, 132, 142, 143, 213, 214, 231, 234, 241, 243, 312, 314, 321, 324, 341, 342, 412, 413, 421, 423, 431, 432 共有24个不同的组合。 ### 三、结论 ...
至于动态规划,虽然在这个问题上不如前两种方法直观,但也可以通过构建一个状态数组来存储已生成的组合,避免重复生成。不过,对于较小规模如6位的数字组合,回溯法和DFS通常是更高效的选择。 易语言作为编程工具,...
有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?字数不够,字数不够,字数不够,字数不够,字数不够,字数不够
# 题目:有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少? # 分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。
标题中的问题旨在探究如何使用1、2、3、4这四个数字来组成没有重复数字的三位数,并且描述中提供了算法思路,即通过三个嵌套的for循环配合一个if语句来实现。在这个Java程序中,`EleventhNumberRange` 类用于解决这...
总结,这个问题是关于使用C语言编程解决一个排列组合问题,通过三重循环生成所有可能的三位数,同时利用条件判断保证数字的唯一性。这个过程体现了程序设计基础、数据结构基础和C语言语法等多方面的知识。
在C#编程中,我们经常会遇到需要解决排列组合问题,比如本题所示的例子:如何用1、2、3、4这四个数字组成互不相同且无重复数字的三位数,并计算总数以及列举出所有可能的组合。这个问题属于组合数学中的全排列问题,...
每个排列占1行,各字符之间无空格分隔,每行由换行符结束。各行之间不必排序,但同一个排列不得重复输出。 【输入样例】 AABB 【输出样例】 AABB ABAB ABBA BABA BAAB BBAA
在这个解决方案中,"可定义输出个数"意味着用户可以设置要生成的不重复数字组合的数量。这可以通过在递归函数外部维护一个计数器来实现,每当输出一个组合时,计数器加1,当达到预设数量时,停止递归。 在给出的`...
2. **组合的计算**:组合的总数用组合数C(n, r)表示,即从n个不同元素中不重复地取出r个元素的组合数。组合数的计算公式为C(n, r) = n! / [r!(n-r)!]。 3. **算法实现**:在编程中,常用递归或动态规划方法实现排列...
在编译原理中,正规式是一...通过这种方式,我们可以构造出一套规则来描述这类字符串,并通过正规式的操作和组合来生成任意长度的无重复数字的字符串正规式。这对于编译器设计和文本处理算法具有重要的理论和实践价值。
System.out.println(chs.length + "取" + n + "不重复的排列组合个数为" + total); } ``` ##### 3.2 重复排列组合 ```java // 重复排列组合 public static int loop(int start, int end, char[] chs, String msg, ...
《重复数字统计器.e文件详解》 在信息技术领域,数据处理和分析是至关重要的环节,尤其是在大数据时代。本文将深入探讨“重复数字统计器...在实际应用中,用户应根据自身需求调整和优化这种组合,以最大化其潜在价值。
易语言源码易语言组合6位不重复数字源码.rar 易语言源码易语言组合6位不重复数字源码.rar 易语言源码易语言组合6位不重复数字源码.rar 易语言源码易语言组合6位不重复数字源码.rar 易语言源码易语言组合6位不...
1、输入n个数(不重复),求n个数字的全排列 如:n=3 全排列的数字为 1 2 3 则输出 123 132 213 231 321 312 2、输入n和k(n》=k)求n个数字的(n,k)排列 如n=3,k=2 输入的三个数位1 2 3 则输出 12 13 21 23 31...
有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
组合数,也称为二项式系数,在组合数学中占有重要地位,通常表示为C(n, k),表示从n个不同元素中不重复地选择k个元素的方法数。 在编程中,计算组合数通常涉及到递归或动态规划。易语言的源码实现可能包括这两种...