产生一个数组的全排列,非冗余 C++实现

finds all the permutaitons of n elements, repeated elements are allowed and do not create redundant permutations.

蛋白质组学Ms-TopDown源代码auxfun.cpp中一个函数,看了很久没有注释,有点晕,但是以后可以直接拿来使用.

产生原始数组元素的全排列,但是要求是非冗余的,也就是说原始数组可以有重复的元素,比如{2,2,2}这个数组,只有一种排列,2这个元素必须按相同处理,只是个数是3

 1 void generate_all_permutations(const vector<int>& org_vector,
 2                                vector< vector<int> >& permutations)
 3 {
 4     unsigned int i;
 5     vector<int> counts, symbols;
 6     permutations.clear();
 7
 8     if (org_vector.size() == 0)
 9         return;
10
11     counts.clear();
12     symbols.clear();
13
14     // create vector with symbols and their counts
15     symbols.push_back(org_vector[0]);
16     counts.push_back(1);
17
18     for (i=1; i<org_vector.size(); i++)
19     {
20         unsigned int j;
21         for (j=0; j<counts.size(); j++)
22         {
23             if (org_vector[i] == symbols[j])
24             {
25                 counts[j]++;
26                 break;
27             }
28         }
29
30         if (j == counts.size())
31         {
32             symbols.push_back(org_vector[i]);
33             counts.push_back(1);
34         }
35     }
36
37     vector<int> next_sym_idx,perm;
38     int n = org_vector.size(); // total number of elements
39     int k = counts.size(); // total number of element types
40     next_sym_idx.resize(n,0);
41     perm.resize(n,-1);
42     int d=0;
43
44     while (1)
45     {
46         while (next_sym_idx[d]<k && counts[next_sym_idx[d]] == 0)
47             next_sym_idx[d]++;
48
49         if (next_sym_idx[0]==k)
50             break;
51
52         if (next_sym_idx[d] >= k)
53         {
54             next_sym_idx[d]=0;
55             d--;
56             counts[next_sym_idx[d]]++;
57             next_sym_idx[d]++;
58             continue;
59         }
60
61         // add symbol
62         perm[d]=symbols[next_sym_idx[d]];
63         counts[next_sym_idx[d]]--;
64         d++;
65
66         if (d == n)
67         {
68             permutations.push_back(perm);
69     //        int k;
70     //        for (k=0; k<perm.size(); k++)
71     //            cout << perm[k] << " ";
72     //        cout << endl;
73
74             d--;
75             counts[next_sym_idx[d]]++;
76             next_sym_idx[d]++;
77         }
78     }
79 }
时间: 2024-10-10 17:21:11

产生一个数组的全排列,非冗余 C++实现的相关文章

17、把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. eg: 输入 3 4 5 1 2 输出 1 思路:用二分法查找最小元素 三种情况: (1)rotateArray[mid] >rotateArray[high]: like:[x,x,x,6,x,x,2],此时最小数字一

给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排序

思路: 桶排序 N个数,设置 N+ 1 个桶,,一定有一个空桶,,为的是保证最大差值一定是不是出现在同一个桶中: 只要比较 非空桶 的最小值,与前一个 非空桶的最大值,求 最大的差值, 1 package my_basic; 2 3 import java.text.Bidi; 4 import java.util.Arrays; 5 6 public class MaxGap { 7 8 /*给定一个数组,求如果排序之后,相邻两数的最大差值,要求时 间复杂度O(N),且要求不能用非基于比较的排

《团队开发一(求一个数组的连续的子数组之和的最大值)》

(1)设计思想:一般的,求一个数组的最大子数组之和即是按数组顺序依次让前几个数的和与下一个数进行比较,设一变量来装每次比较后的较大的数,依此进行到数组终端:但是考虑到求的是连续的子数组,则应该想到除了在按顺序上的连续外,还得考虑到末端与首端的连续,所以按数组顺序依次求解得到的未必就是连续的最大的子数组之和,故此必须在此种情况下也求解出最大子数组之和,方法即是同时从数组的两端依次进行求出各自的最大子数组之和,然后在相遇前求和后与之前所求的最大子数组之和依次相比较,取它们中最大的一个作为连续的最大子

数组的全排列

1.问题背景 学过数学的人都知道,全排列的意思是什么.现在如何用计算机的编程语言实现数组的全排列呢? 数组的全排列可用于求解八皇后问题,具体参见:全排列解决八皇后问题.与此同时,全排列经常会出现在笔试或者面试,如求字符串的全排列.之所以那它作为考题,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平.所以,掌握它很重要. 2.全排列的递归实现 2.1求解思路 全排列表示把集合中元素的所有按照一定的顺序排列起来,使用P(n, n) = n!表示n个元素全排列的个数

【LeetCode】下一个排列与全排列问题

(一)下一个排列 题目(Medium):31. 下一个排列 题目描述: ??实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. ??如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). ??必须原地修改,只允许使用额外常数空间. ??以下是一些例子,输入位于左侧列,其相应输出位于右侧列. ??1,2,3 → 1,3,2 ??3,2,1 → 1,2,3 ??1,1,5 → 1,5,1 解题思路: ??本题有一个比较固定的算法思路,可以总结为以下

【转】一个数组中有三个数字a、b、c只出现一次,其他数字都出现了两次。请找出三个只出现一次的数字。

转自:http://zhedahht.blog.163.com/ 题目:一个数组中有三个数字a.b.c只出现一次,其他数字都出现了两次.请找出三个只出现一次的数字. 分析:在博客http://zhedahht.blog.163.com/blog/static/2541117420071128950682/中我们讨论了如何在一个数组中找出两个只出现一次的数字.在这道题中,如果我们能够找出一个只出现一次的数字,剩下两个只出现一次的数字就很容易找出来了. 如果我们把数组中所有数字都异或起来,那最终的结

求数组的全排列

给定一个数组,求出全排列的情形? 算法描述: /** - 给定数组 3 4 6 9 8 7 5 2 1 如何求出紧挨着的下一个排列? step1:从后面扫描,找到第一个下降的数(6),并记录: step2:依然从后面扫描,找到第一个大于step1(6)的数7,并记录: step3:交换step1(6).step2(7):=>3 4 7 9 8 6 5 2 1 step4:在step(7)之后的数字,首尾互换 =>3 4 7 1 2 5 6 8 9即为所求 */ static int count

字符串全排列-非递归算法

字符串的全排列非递归算法是每次都寻找比前序列大一点的序列,如: 起点:字典序最小的排列,例如12345 终点:字典序最大的排列,例如54321 过程:从当前排列生成字典序刚好比它大的下一个排列. 算法过程:后找.小大.交换.翻转 后找:字符串中最后一个升序的位置i,即S[k]>S[k+1](k>i),S[i]<S[i+1]: 查找(小大):S[i+1...N-1]中比Ai大的最小值Sj: 交换:Si,Sj: 翻转:S[i+1...N-1] 代码如下: 1 #include <ios

七、如何在Java中高效检查一个数组是否含有一个值

如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非常不同.在下面,我将会展示每种方法的时间花费. 一.四种不同的方法去检查一个数组包含特定的值 1) 用List public static boolean useList(String[] arr, String targetValue) { return Arrays.asList(arr).co