作业2.有重复全排列和无重复全排列的区别

Posted

tags:

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

参考技术A 无重复全排列即在排列中没有重复元素,有重复全排列即在排列中有重复元素。
n个有重复元素全排列:无重复的全排列为序列头元素与所有元素进行交换共n种情况,每种情况的后n-1位元素构成新的序列。
全排列(含有重复元素)给定一个可包含重复数字的序列,返回所有不重复的全排列。

有重复元素的全排列

这是我的代码: #include <stdio.h> #include "stdlib.h" inline void Swap(char& a, char& b) // 交换a和b char temp = a; a = b; b = temp; void Perm(char list[], int k, int m) //生成list [k:m ]的所有排列方式 int i; if (k == m) //输出一个排列方式 for (i = 0; i <= m; i++) putchar(list[i]); putchar('\n'); 为什么输出结果不是Sample Input 输入 4 aacc 输出 aacc acac acca caac caca ccaa 6
#include <stdio.h>
#include "stdlib.h"
inline void Swap(char& a, char& b)
// 交换a和b
char temp = a;
a = b;
b = temp;


void Perm(char list[], int k, int m)
//生成list [k:m ]的所有排列方式
int i;
if (k == m) //输出一个排列方式
for (i = 0; i <= m; i++)
putchar(list[i]);
putchar('\n');

else // list[k:m ]有多个排列方式
// 递归地产生这些排列方式
for (i=k; i <= m; i++)
if(list[k]!=list[i])
Swap (list[k], list[i]);
Perm (list, k+1, m);
Swap (list [k], list [i]);


int main()
int i,k,j;

scanf("%d",&i);

char s[i];
for(k=0;k<i;k++)
scanf("%c",&s[k]);
// char s[]="abc";

Perm(s, 0,j);

system("pause");

return 0;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
// 字符串最大长度
#define MAX_STRING_LENGTH 50
// 全排列顺序。TRUE:按字母序升序;FALSE:按字母序降序。
#define PERMUTATION_ASSCENDING_ORDER TRUE
// qsort 函数使用的比较函数
int compare(const void *a, const void *b)

return PERMUTATION_ASSCENDING_ORDER
? *((char*)a) - *((char*)b)
: *((char*)b) - *((char*)a);

/*
无重复全排序。
参数:
str 要进行无重复全排序的字符串。
字符串内字符必须已经排序过(升序或降序都可以)

isUsed 如果 isUsed[i] = TRUE 表示 str[i] 已经加入当前排列中

p 当前排列中已经存在的字符数

buffer 当前的排列。
buffer[0]~buffer[p-1] 是 str 中已经加入排列的字符。

返回:
无重复全排序的总数。
*/
int Perm(char str[],int isUsed[],int p ,char buffer[])

int len=strlen(str),i,j,total=0;

if(p == len)
// 输出一个全排列
printf("%s\n",buffer);
return 1;


for(i=0;i<len;i++)

if(!isUsed[i])

// 查询当前字符的后面,是否已经有和当前字符相同的字母加入了全排序中。
for(j=i+1;j<len;j++)
if(str[i]==str[j] && isUsed[j])
break;

if(j == len)
// 当前字符的后面,没有和当前字符相同的字母加入了全排序中。
// 当前字符可以加入全排序

isUsed[i] = TRUE;
buffer[p] = str[i];
total += Perm(str,isUsed,p+1,buffer);
isUsed[i] = FALSE;



return total;


int main(int argc, char *argv[])

char str[MAX_STRING_LENGTH]="aacc";
char buffer[MAX_STRING_LENGTH]=0;
int isUsed[MAX_STRING_LENGTH]=0;

while(scanf("%s",str)!=EOF)

// 先按字母序排序
qsort(str,strlen(str),sizeof(str[0]),compare);
// 全排列
printf("Total %d\n\n",Perm(str,isUsed,0,buffer));

return 0;
参考技术A 代码不全!~ 没有主函数。
把函数改成:
void Perm(char list[], int k, int m)
//生成list [k:m ]的所有排列方式
int i;
if (k == m) //输出一个排列方式
for (i = 0; i <=m; i++)
putchar(list[i]);
putchar('\n');

else // list[k:m ]有多个排列方式
// 递归地产生这些排列方式
for (int t,i=k; i <=m; i++)
//查找以前是否出现过
for(t=k;t<i;t++)

if(list[t]==list[i])
break;

if(t==i)

Swap (list[k], list[i]);
Perm (list, k+1, m);
Swap (list [k], list [i]);




另外主函数测试可写成:
int main() int i,k,j;
//scanf("%d",&i);
//for(k=0;k<i;k++)
//scanf("%c",&s[k]);
char s[]="aacc";

Perm(s, 0,4-1);
system("pause");
return 0;

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

LeetCode:全排列II47

有重复元素的全排列

leetcode 47. 全排列 II---回溯篇6

LeetCode(47):全排列 II

全排列:不含重复元素和含重复元素的全排列

递归与回溯14:排列问题,有重复元素的全排列