含重复元素的全排列


借鉴自:Loyalch的博客

             jeiwt的专栏


算法思想:递归

input: 字符数组str[],例如:str[] = {a,a,b,b,c};

先对输入序列str[]排序,输出序列A[]可以看成A[0] + A[1...Len] 组合而成,而其中A[0]可以是a[0...len]中不同的数。若是a[i]被选中作为a[0],则可以当做str[0]与str[i]交换;

同理A[1...Len]又可以是由A[1] + A[2...Len]组合而成,其中A[1]可以是a[1...Len]中不同的数,如上。

代码:

 #include <iostream>
 #include <algorithm>
 #include <cstdio>
 using namespace std;
 long long ans;
 int ok(char str[],int a ,int b )
 {
          if(b>a)
           for(int i=a;i<b;i++)
              if(str[i]==str[b])
                  return 0;
           return 1;
 }
 void perm(char str[],int k,int m)
 {
           int i;
           if(k==m)
           {
              ans++;
              for(i=0;i<=m;i++)
                  printf("%c",str[i]);
              printf("\n");
              return ;
           }
           else for(i=k;i<=m;i++)
                   if(ok(str,k,i))
                   {
                           swap(str[k],str[i]);
                           perm(str,k+1,m);
                           swap(str[k],str[i]);
                   }
 }
 int main()
 {
      char str[505];
      int n,i;
      scanf("%d",&n);
      getchar();
      ans=0;
      for(i=0;i<n;i++)
          scanf("%c",&str[i]);
      perm(str,0,n-1) ;
      printf("%lld\n",ans);
      return 0;
 }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重复元素全排列流程图如下: 1. 首先将字符串按照字典序排序,以便后续判断重复元素。 2. 从第一个元素开始,依次与后面的元素交换位置,直到最后一个元素。 3. 在交换过程中,判断是否有重复元素即将被交换,如果有则跳过这次交换。 4. 交换完成后,将当前元素与下一个元素交换位置,重复步骤3。 5. 当交换到最后一个元素时,输出当前排列结果。 举个例子,对于字符串"abb"的全排列流程如下: 1. 首先将字符串按照字典序排序,得到"abb"。 2. 从第一个元素"a"开始,依次与后面的元素交换位置,得到"bab"和"bba"。 3. 在交换过程中,判断是否有重复元素即将被交换,发现"b"即将与"b"交换,跳过这次交换。 4. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 5. 交换到最后一个元素,输出当前排列结果"abb"。 6. 从第二个元素"b"开始,依次与后面的元素交换位置,得到"bab"和"bba"。 7. 在交换过程中,发现"b"即将与"a"交换,跳过这次交换。 8. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 9. 交换到最后一个元素,输出当前排列结果"abb"。 10. 从第三个元素"b"开始,依次与后面的元素交换位置,得到"abb"和"abb"。 11. 在交换过程中,发现"b"即将与"b"交换,跳过这次交换。 12. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 13. 交换到最后一个元素,输出当前排列结果"abb"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值