zoukankan      html  css  js  c++  java
  • 有重复元素的排列问题

    参考:http://blog.sina.com.cn/s/blog_9b95c19e0101aqwn.html

    Description
    设R={ r1, r2, ……, rn }是要进行排列的n个元素。其中元素r1 ,r2 ,……,rn可能相同。试设计一个算法,列出R的所有不同排列。

    给定n以及待排列的n个元素。计算出这n个元素的所有不同排列。
    Input
    输入数据的的第1行是元素个数n,1≤n≤500。接下来的1行是待排列的n个元素。
    Output
    将计算出的n个元素的所有不同排列输出,每种排列占1行,最后1行中的数是排列总数。
    Sample Input
    4 aacc
    Sample Output
    aacc
    acac
    acca
    caac
    caca
    ccaa
    6

    其实呢,这个问题和普通求全排列问题差不多,只是多了“判断是否重复字符”的过程而已。

    下面的代码是原文作者写的,改为c版本。

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 long long ans;
     5 int ok(char str[],int a ,int b ) //检测第b个元素是否能放在第a个位置
     6 {
     7     int i;
     8     if(b>a)
     9     {
    10         //若是前面有一个元素a[i]与a[b]相等,
    11         //那a[b]的值已经在第a个位置出现过,再放在这个地方就是重复了。
    12         for(i=a;i<b;i++)
    13             if(str[i]==str[b]) return 0;
    14     }
    15     return 1;
    16 }
    17 void perm(char str[],int k,int m)
    18 {
    19     char temp;
    20     int i;
    21     if(k==m)
    22     {
    23         ans++;
    24         for(i=0;i<=m;i++)
    25             printf("%c",str[i]);
    26         printf("
    ");
    27         return ;
    28     }
    29     else for(i=k;i<=m;i++)
    30     if(ok(str,k,i))  //检测第i个元素是否能放在第k个位置
    31     {
    32         temp=str[k];str[k]=str[i];str[i]=temp;//swap(str[k],str[i]);
    33         perm(str,k+1,m);
    34         temp=str[k];str[k]=str[i];str[i]=temp;//swap(str[k],str[i]);
    35     }
    36 }
    37 int main()
    38 {
    39     char str[505];
    40     int n,i;
    41     scanf("%d",&n);
    42     getchar();
    43     ans=0;
    44     for(i=0;i<n;i++)
    45         scanf("%c",&str[i]);
    46     perm(str,0,n-1);
    47     printf("%lld
    ",ans);
    48     return 0;
    49 }

    这段代码是对上述问题的求解。下面改一下上述代码,对n个可能含有重复元素的整数进行全排列

     1 //参考:http://blog.sina.com.cn/s/blog_9b95c19e0101aqwn.html
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 
     5 long long ans;
     6 int ok(int str[],int a ,int b ) //检测第b个元素是否能放在第a个位置
     7 {
     8     int i;
     9     if(b>a)
    10     {
    11         //若是前面有一个元素a[i]与a[b]相等,
    12         //那a[b]的值已经在第a个位置出现过,再放在这个地方就是重复了。
    13         for(i=a;i<b;i++)
    14             if(str[i]==str[b]) return 0;
    15     }
    16     return 1;
    17 }
    18 void perm(int str[],int k,int m)
    19 {
    20     int temp;
    21     int i;
    22     if(k==m)
    23     {
    24         ans++;
    25         for(i=0;i<=m;i++)
    26             printf("%-4d ",str[i]);
    27         printf("
    ");
    28         return ;
    29     }
    30     else for(i=k;i<=m;i++)
    31     if(ok(str,k,i))  //检测第i个元素是否能放在第k个位置
    32     {
    33         temp=str[k];str[k]=str[i];str[i]=temp;//swap(str[k],str[i]);
    34         perm(str,k+1,m);
    35         temp=str[k];str[k]=str[i];str[i]=temp;//swap(str[k],str[i]);
    36     }
    37 }
    38 int main()
    39 {
    40     int str[505];
    41     int n,i;
    42     scanf("%d",&n);
    43 
    44     ans=0;
    45     for(i=0;i<n;i++)
    46         scanf("%d",&str[i]);
    47     perm(str,0,n-1);
    48     printf("%lld
    ",ans);
    49     return 0;
    50 }

    至于 “对长度为n,可能含有重复元素的序列,选择r个元素做排列” 这样的问题,暂时没有想到比较好的思路了。

  • 相关阅读:
    浅谈 倍增/ST表
    Meetings S 题解
    排序模板
    Huffman 树
    2020.7.31 模拟赛 题解
    浅谈 最短路
    【lcez校内第三次考T1】【题解】folder
    【题解】 P2613 【模板】有理数取余
    【题解】P5535 【XR-3】小道消息
    【笔记】积性函数 与 欧拉函数
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/4748174.html
Copyright © 2011-2022 走看看