/*
生成可重集得到排列:
把问题改成:输入数组P,并按字典序输出数组A各元素的所有全排列,则需要对上述程序进行修改--把P加到printPermutation的参数列表中,然后把
代码中的if(iArr[i] == j) 和if(A[pos] == j)改成if(iArr[i] == P[j]) 和 iArr[pos] = P[j]
bug1:如果数组中是重复的元素 1 1 1的话 ,因为禁止出现重复,造成错误
解决方法:统计iArr[0]~iArr[pos-1]中P[i]的出现次数c1,以及P数组中P[i]出现的次数c2。只要c1<c2,就可以递归
bug2:如果111重复,也输出27次。枚举的下标应该不重复,不遗漏取遍所有p[i]值。只需检查p的第一个元素和所有前一个元素不相同。
思路:
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 1024
void printPermutation(int* iArr,int pos,int n,int* iPer)
{
if(pos == n)
{
for(int k = 0 ; k < n;k++)
{
printf("%d ",iArr[k]);
}
printf("\n");
return;
}
for(int i = 0;i < n;i++)
{
if(!i || iPer[i] != iPer[i-1])//判断当前元素与前面元素不能重复,否则遇111这种数组,会有重复输出
{
//统计iArr[0]到iArr[pos-1]中iPer[i]出现的次数
int iCount1 = 0;
for(int j = 0; j < pos;j++)
{
if(iArr[j] == iPer[i])
{
iCount1++;
}
}
int iCount = 0;
//统计iPer[i]在数组中出现次数
for(int m = 0; m < n ;m++)
{
if(iPer[i] == iPer[m])
{
iCount++;
}
}
//if(!isAppear)
if(iCount1 < iCount)//判断重复的条件应该改成出现次数的判断
{
iArr[pos] = iPer[i];//把第iPos个元素确定下来之后进行后续递归
printPermutation(iArr,pos+1,n,iPer);
}
}
}
}
int main(int argc,char* argv[])
{
int n;
while(EOF != scanf("%d",&n))
{
int iArr[MAXSIZE];
int iPer[MAXSIZE];
int j = 0;
for(int i = 0; i < n;i++)
{
scanf("%d",&iPer[j++]);
}
printPermutation(iArr,0,n,iPer);
}
system("pause");
return 0;
}