如何得到有重复元素的不重复全排列

 M个元素中含有相同的元素,如何得到他们的全排列(不重复排列)?

元素表述:   a1,a1,...a1,   a2,a2,...a2,.......,an,an,...an
  其中,a1的个数为N1,   a2的个数为N2,以此类推,总个数为M。

则可以证明不重复的排列种类的数目:   M!/(N1!*N2!*...*Nn!)

 

 就是将N个数字做全排列。不过对于某些数字不能选择而已。
这里只要限制将要选择的数字必须大于原来已经选择的数字就可以达到目标。
下面是递归算法

#include <stdio.h> 
#define   N   5 


void   arrange(int   rec[],int   used[],int   depth); 
void   write(int   rec[],   int   maxdepth); 
int   a[N]={1,1,2,2,3};   //这些值必须升序排列且大于0 
int   count=0; 

int   main() 
{int   rec[N+1]={0},used[N+1]={0}; 
  
    arrange(rec,used,0);   
    printf( "\ncount=%d ",count); 
    getchar(); 
    return   0; 
}     

void   write(int   rec[]) 
{   int   i; 
    for(i=0;i <N;i++) 
          printf( "%4d ",a[rec[i]]); 
    printf( "\n "); 
    count++; 
} 

void   arrange(int   rec[],int   used[],int   depth) 
{ 
  int   i,found_num; 
    if   (depth> =N)   write(rec);   //找到了一个可行解,输出 
    else 
      {found_num=0;               //增加这个变量记录原来本结点存储的数字 
        for(i=0;i <N;i++)     //   搜索该结点的孩子结点   
        {//如果该下标在前面还没有使用过,且该下标所指示的数字比 
          //原先所放置的数字要大,则是一个部分解 
            if(used[i]==0   &&   a[i]> found_num   )   
            {   rec[depth]=i;       //记录下该结点放置的下标   
                found_num=a[i];   //记录下本结点存放的数字   
                used[i]=1;             //   标记该下标已经被使用 
                arrange(rec,used,depth+1);       //   扩展,进入孩子结点继续搜索   
                used[i]=0;           //退回来后要清除本结点所记录下标的使用记录 
            } 
        }     
    } 
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值