Ka的回溯编程练习 Part6.5|详解|有重复元素的排列问题

#include <stdio.h>
#define br printf("
");
int ans=0;
char el[502]; 
int confirm(int i,int k) //往回比较,如果元素有相同跳过此情况 
{
    if(i>k)
    {
        while(i>k)
        {
            if(el[i]==el[k]) return 0;
            k++;
        }
    }
    return 1; 
}
void op(int n)
{
    ans++;
    int j;
    for(j=0;j<=n;j++) printf("%c",el[j]);
    br
}
void perm(int n,int k) 
//n代表当前距离分配结束的个数(数组模式,-1) k代表当前元素的位置 
{
    int i,r;
     if(n==k) op(n);  //如果两个数已经达到相等 输出 
    else for(i=k;i<=n;i++)  //从当前数组元素开始一直到末尾,逐个进行交换
        if(confirm(i,k))//根据返回结果进行交换 
        {
            r=el[i];el[i]=el[k];el[k]=r;
            perm(n,k+1); //推进k的一位
             r=el[i];el[i]=el[k];el[k]=r;
        } 
}
int main()
{
    int n,i;
    scanf("%d",&n);
    getchar();
    for(i=0;i<n;i++)
        scanf("%c",&el[i]);   //以上是普通的输入环节 
    perm(n-1,0);
    printf("%d",ans);
    return 0;
}

原谅我的恶趣味哈哈哈。

整个思路是这样的:

a a c c

0 1 2 3

首先和自己交换一次

 a c c

 a c c 后方字母乱序

然后递归下去,不停地把往后每个字符都代到当前位置寻找下一步情况。

c a a c

如果不是在和自己交换,那么检测一下是否在之前交换过同样的元素。比如:

a b c   f e h

a b c e d f e h 后方字母乱序

如果下一次和下一个e交换,那么效果和第一个e相同,都是后面顺序不管,abce往下找。

a b c d e f  h

a b c e e f d h

检测要从前往后找,这样能找到第一位的

a b c d e f e h

      k     i

a b c d e f e h

        k   i 相等,跳过此情况

慢慢体会吧。应该很清楚了

原文地址:https://www.cnblogs.com/KakagouLT/p/4564189.html