有重复全排列

Posted yuyaweibest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有重复全排列相关的知识,希望对你有一定的参考价值。

有重复全排列_递归实现

  **问题描述:**M个元素中含有相同的元素,如何得到他们的全排列(不重复排列)?
  **元素表述:**a1,a1,…a1, a2,a2,…a2,…….,an,an,…an
       其中,a1的个数为N1, a2的个数为N2,以此类推,总个数为M。
  则可以证明不重复的排列种类的数目: M!/(N1!N2!…*Nn!)
  
  解题思路与方案:
  无重复递归全排列的思想是第一个字符依次分别与后面字符(包含它本身)交换,然后除去交换后的第一个字符,剩下的字符再递归全排,全排后再交换回来至最初字符串,依次循环下去,直到第一个字符与所有字符均交换一遍。我们只需设好边界条件以结束递归,输出所有排列。
  类比,为解决本次问题,我们可以加上这样的判断:这个字符本身与本身可以相互交换,如果一个字符与后面的字符相同,那么这二个字符就不交换。如”122”,第一个字符与本身交换得到“122”,第一个字符“1”与第二个字符“2”交换得到“212”,然后考虑第一个字符“1”1与第三个字符“2”交换,此时由于第三个字符等于第二个字符,所以第一个字符不再与第三个字符交换。再考虑“212”,它的第二个字符与第三个字符交换可以得到解决“221”。此时全排列生成完毕。
  由此,我们得到了有重复全排列的核心思想:设定好边界条件以结束递归,然后从第一个字符起分别与它后面非重复出现的字符交换(包含本身的交换),再递归全排,全排后再交换回来至最初字符串,依次循环下去,直到第一个字符与所有字符都交换过。
  用编程语言描述:第i个字符与第j个字符交换时,如果[i,j)中没有与第j个数相等的字符则返回true,如果有则返回false;字符本身与本身交换返回true。

C++代码实现:

#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
void Swap(char* a,char* b);
bool IsSwap(char *pStr,int begin,int end);
void AllRange(char* pStr,int k,int m);
void Foo(char* pStr);
int main()
    char szStr[]="baaca";
    cout<<szStr<<"的排列组合如下:\\n";
    Foo(szStr);
    cin.get();
    return 0;

void Swap(char* a,char* b)             //交换字符
    char t=*a;
    *a=*b;
    *b=t;

bool IsSwap(char *pStr,int begin,int end)   //参见编程语言的实现
    for(int h=begin;h<end;h++)
        if(pStr[h]==pStr[end])
            return false;
    return true;

void AllRange(char* pStr,int k,int m)
    if(k==m)                                // 结束递归的边界条件
      
        static int s_i=1;
        cout<<"  第"<<s_i<<"个排列 "<<pStr<<endl;
        s_i++;
    
    else
    
        for(int i=k;i<=m;i++)
        
            if(IsSwap(pStr,k,i))           //根据IsSwap()函数返回值来决定要不要交换字符
            
                Swap(pStr+k,pStr+i);
                AllRange(pStr,k+1,m);      
                Swap(pStr+k,pStr+i);
            
        
    

void Foo(char* pStr)
    AllRange(pStr,0,strlen(pStr)-1);

输出:

其他测试类似(只需改变szTextStr字符串),均能输出正确结果,实验成功!

以上是关于有重复全排列的主要内容,如果未能解决你的问题,请参考以下文章

有重复元素的全排列

有重复全排列

常见的算法问题全排列

有重复元素的全排列

带重复的全排列问题

LeetCode47, 全排列进阶,如果有重复元素怎么办?