企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
https://blog.csdn.net/qq1519932709/article/details/17176813 对于n个不同元素集合R的全排列问题,可以用一个简单递归的公式表达:      当n = 1时,   P(R) = r, 否则      P(R) = ri + P(R - {ri})       (i = 1, 2, ..., n) P(R) : 不含重复元素的R集合的全排列 +: 表示连接   根据上面的公式写出递归计算出无重复元素序列的全排列: Perm(Type list[], int k, int m)    if  k=m       then  print( list )     else        for i=k  to  m  do             Swap( list[k],list[i] );             Perm(list,k+1,m);             Swap(list[k],list[i]);   1. 对于含有重复元素的序列,我们不能再像上面那样简单的交换与来求解。因为,当ri 到rk 的序列中,如果存在元素 rj = rk 且 j != k 。这时,rj 必然是已经和 ri 交换过位置,并且计算了 rj + P(R{i...n} - {rj}) 。如果再将 rk 与 ri  与交换,则会得到 rk + P(R{i...n} - {rk}) 这个全排列,而rj = rk,所以,我们第二次计算多余了。 2. 再考虑当从ri  到rk 的序列中,如果不存在有元素 rj = rk , 那么,这时的情况是和普通计算时过程一样,交换ri  与rk 然后求解 就可以了,因为即使在后面存在与其他重复元素,我们也会在计算中按第1步剪掉重复计算。 所以,在求解时我们只要保证交换某一元素时,其未有在i...j之间出现过。否则交换后必会重复求解。 下面是求有重复元素的全排列的源码(我参考网上的写的): int ok(char *origin, int x, int y) { int i; if(y > x) for(i = x; i < y; i++) if(origin[i] == origin[y]) return 0; return 1; } void permutation(char *origin, int curLen, int maxLen) { int i; if(curLen >= maxLen - 1) { puts(origin); fprintf(fpout, "%s\n", origin); } else { for(i = curLen; i < maxLen; i++) if(ok(origin, curLen, i)) { swap(&origin[i], &origin[curLen]); permutation(origin, curLen + 1, maxLen); swap(&origin[i], &origin[curLen]); } } --------------------- 作者:qq1519932709 来源:CSDN 原文:https://blog.csdn.net/qq1519932709/article/details/17176813 版权声明:本文为博主原创文章,转载请附上博文链接!