当前位置:编程学习 > C/C++ >>

递归方法求不重复排列

[cpp]
/*******************************************************************\
输入n个数,输出由这n个数构成的排列,不允许出现重复的项
输入:
3
1 1 2
输出:
1 1 2
1 2 1
2 1 1
思路:
先手工模拟排列的过程,在第三个排列2 1 1中,我们之所以能够写出来,是因为
我们能发现1和2是不同的数,而计算不能,因此在存储数据的时候数组中不能有
重复的数据,因此存储的数比实际的数据个数要少,因此要用辅助数组记录每个
元素的个数,这样就能利用不含重复元素的排列算法求解.
\*******************************************************************/ 
#include<stdio.h>  
#include<string.h>  
#include<assert.h>  
 
const int maxn = 100; 
 
int num[maxn]; 
int used[maxn]; 
int ans[maxn]; 
int n, m; 
 
int readdata() 

    memset(used, 0, sizeof(used)); 
    memset(num, 0, sizeof(num)); 
    memset(ans, 0, sizeof(ans)); 
    int i = 0, j = 0; 
    if(scanf("%d", &n) == EOF || n <= 0) 
        return false; 
    int val = 0; 
    for(i=0; i<n; i++) 
    { 
        scanf("%d", &val); 
        for(j=0; j<m; j++) 
        { 
            if(num[j] == val) 
            { 
                used[j]++; 
                break; 
            } 
        } 
        if(j == m) 
        { 
            num[m] = val; 
            used[m] = 1; 
            m++; 
        } 
    } 
    return true; 

 
void output() 

    for(int i=0; i<n; i++) 
    { 
        if(i < n-1) 
            printf("%d ", ans[i]); 
        else 
            printf("%d\n", ans[i]); 
    } 

 
void unrepeatPerm(int dep) 

    if(dep >= n) 
    { 
        output(); 
        return; 
    } 
    for(int i=0; i<m; i++) 
    { 
        /*最好是手写模拟递归过程,其中num数组中存储的是不同的元素,这也是关键,*/ 
        if(used[i] > 0)/*此处是重点*/ 
        { 
            used[i]--; 
            ans[dep] = num[i];  
            unrepeatPerm(dep+1); 
            used[i]++; 
        } 
    } 

 
int main() 

    while(readdata()) 
    { 
        unrepeatPerm(0); 
    } 
    return 0; 

/*******************************************************************\
输入n个数,输出由这n个数构成的排列,不允许出现重复的项
输入:
3
1 1 2
输出:
1 1 2
1 2 1
2 1 1
思路:
先手工模拟排列的过程,在第三个排列2 1 1中,我们之所以能够写出来,是因为
我们能发现1和2是不同的数,而计算不能,因此在存储数据的时候数组中不能有
重复的数据,因此存储的数比实际的数据个数要少,因此要用辅助数组记录每个
元素的个数,这样就能利用不含重复元素的排列算法求解.
\*******************************************************************/
#include<stdio.h>
#include<string.h>
#include<assert.h>

const int maxn = 100;

int num[maxn];
int used[maxn];
int ans[maxn];
int n, m;

int readdata()
{
 memset(used, 0, sizeof(used));
 memset(num, 0, sizeof(num));
 memset(ans, 0, sizeof(ans));
 int i = 0, j = 0;
 if(scanf("%d", &n) == EOF || n <= 0)
  return false;
 int val = 0;
 for(i=0; i<n; i++)
 {
  scanf("%d", &val);
  for(j=0; j<m; j++)
  {
   if(num[j] == val)
   {
    used[j]++;
    break;
   }
  }
  if(j == m)
  {
   num[m] = val;
   used[m] = 1;
   m++;
  }
 }
 return true;
}

void output()
{
 for(int i=0; i<n; i++)
 {
  if(i < n-1)
   printf("%d ", ans[i]);
  else
   printf("%d\n", ans[i]);
 }
}

void unrepeatPerm(int dep)
{
 if(dep >= n)
 {
  output();
  return;
 }
 for(int i=0; i<m; i++)
 {
  /*最好是手写模拟递归过程,其中num数组中存储的是不同的元素,这也是关键,*/
  if(used[i] > 0)/*此处是重点*/
  {
   used[i]--;
   ans[dep] = num[i];
   unrepeatPerm(dep+1);
   used[i]++;
  }
 }
}

int main()
{
 while(readdata())
 {
  unrepeatPerm(0);
 }
 return 0;
}

 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,