33,028
社区成员




#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
//生成有重复元素的全排列
//作者:liangbch@263.net, 2008-11-14
//#define _MY_DEBUG
#ifdef _MY_DEBUG
#define MAX_LEN 8
#else
#define MAX_LEN 256 //最多可以生成256个数的全排列
#endif
typedef struct _pair
{
int v; //value
int c; //count
}PAIR;
void printPermutation( int data[],int len)
// len: data 数组的长度
{
int i;
for (i=0;i<len;i++)
{
if (i==0)
printf("%d",data[i]);
else
printf(",%d",data[i]);
}
printf("\n");
}
void permutation( int newData[],
PAIR arrCount[],
int len,int level)
// len:countArray 数组元素的个数
// level: newData 数组已被填充的元素的个数
{
int i,j;
bool bFind=false;
PAIR tArray[MAX_LEN];
for (i=0;i<len;i++)
{
for (j=0;j<len;j++) //复制数组从arrCount到tArray
tArray[j]=arrCount[j];
if ( tArray[i].c>0)
{
bFind=true;
newData[level]= tArray[i].v;
tArray[i].c--;
#ifdef _MY_DEBUG
printf("#tArray[%d].c=%d\n",i,tArray[i].c);
printf("#new item= data[%d]=%d\n",level,tArray[i].v);
#endif
permutation( newData,tArray,len,level+1);
}
}
if (!bFind)
{
printPermutation(newData,level);
}
}
//输出data各个元素的一个全排列
//数组data中的各个元素必须以非递减排序,数组中元素可以重复
//假如有n个元素,则这个算法的空间复杂度为n*n,递归深度为n
void printAllPermutation(int data[],int n)
{
PAIR countArray1[MAX_LEN];
int newData[MAX_LEN];
int i,j;
//根据data初始化countArray1
countArray1[0].v=data[0];
countArray1[0].c=1;
for (j=0,i=1;i<n;i++)
{
if ( data[i]== countArray1[j].v)
{
countArray1[j].c++;
}
else
{
j++;
countArray1[j].v=data[i];
countArray1[j].c=1;
}
}
permutation( newData,countArray1,j+1,0);
}
int main(int argc, char* argv[])
{
//int a[]={2,3,5};
int a[]={2,2,3,5};
//int a[]={2,2,3,3,5};
printAllPermutation(a,sizeof(a)/sizeof(int));
return 0;
}
#include <stdio.h>
inline void Swap(int& a, int& b)
{
// 交换a和b
int temp = a;
a = b;
b = temp;
}
//该程序有csdn dobear_0922 提供
//生成list [k:m ]的所有排列方式
void Perm(int list[], int k, int m)
{
int i;
if (k == m) //输出一个排列方式
{
for (i = 0; i <= m; i++)
{
if (i==0)
printf("%d",list[i]);
else
printf(",%d",list[i]);
}
printf("\n");
}
else // list[k:m ]有多个排列方式
{
// 递归地产生这些排列方式
for (i=k; i <= m; i++)
{
Swap (list[k], list[i]);
Perm (list, k+1, m);
Swap (list [k], list [i]);
}
}
}
void dobear_0922() //不能将数组
{
int a[]={2,2,3,5};
Perm(a, 0, 2); // 没有去掉 重复 元素
}
#define N 10
bool is_used[N];
int result[N];
void init(int n)
{
for (int i = 0; i < n; i++)
{
is_used[i] = false;
}
}
int test(int input[], int n, int k)
{
int ret = 0;
if (k == n)
{
for (int i = 0; i < n; i++)
{
printf("%d ",result[i]);
}
printf("\n");
return 1;
}
for (int i = 0; i < n; i++)
{
if (is_used[i] == false)
{
if (i == 0)
{
is_used[i] = true;
result[k] = input[i];
ret += test(input,n,k + 1);
is_used[i] = false;
}
else
{
if (input[i - 1] != input[i])
{
is_used[i] = true;
result[k] = input[i];
ret += test(input,n,k + 1);
is_used[i] = false;
}
if (input[i - 1] == input[i] && is_used[i - 1] == true)
{
is_used[i] = true;
result[k] = input[i];
ret += test(input,n,k + 1);
is_used[i] = false;
}
}
}
}
return ret;
}
int currenttt()
{
int input[] = {2, 2, 3} ;
int n=sizeof(input)/sizeof(int);
int num;
init(n);
num= test(input,n,0);
printf("\ntotal %d permutation\n",num);
return 0;
}
/*
顾名思义,这种方法的思想就是将所有n元排列按"字典顺序"排成队,以12…n为第一个排列,排序的规则,也就是由一个排列(p)=(p1p2…pn)直接生成下一个排列的算法可归结为
(1) 求满足关系式p[k-1]<p[k] 的k的最大值,设为i,
(2) 求满足关系式p[i-1]<p[k] 的k的最大值,设为j,
(3) p[i-1] 与p[j] 互换位置得
(q)=(q1 q2 … qn);
(4) (q)=(q1 q2 … qi-1 qi qi+1 … qn)中qi qi+1 … qn部分的顺序逆转,得
q1 q2 … qi-1 qn…qi+1 qi
这便是所求的下一个排列。
*/
void print_permutation(int *a,int n)
{
int i;
for (i=0;i<n ;i++ ) printf("%3d ",a[i]);
printf("\n");
}
void swap(int *a,int i,int j)
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
void permutation(int *a,int n)
{
int i,j,k;
print_permutation(a,n);
for (i=n-1;i>0 && a[i]<=a[i-1];i-- ) ;
if (i==0)
return;
for (j=n-1;j>0 && a[j]<=a[i-1];j-- ) ;
swap(a,i-1,j);
for (j=i,k=n-1;j<k;j++,k--)
swap(a,j,k);
permutation(a,n);
}
int tailzhou()
{
int num[]={2,2,3};
permutation(num,sizeof(num)/sizeof(int));
return 0;
}
//provide by tailzhou 2
void permutation2(int *a,int n)
{
int i,j,k;
while(1)
{
print_permutation(a,n);
for (i=n-1;i>0 && a[i]<=a[i-1];i-- ) ;
if (i==0)
return;
for (j=n-1;j>0 && a[j]<=a[i-1];j-- ) ;
swap(a,i-1,j);
for (j=i,k=n-1;j<k;j++,k--)
swap(a,j,k);
}
}
int tailzhou2()
{
int num[]={2,2,3};
permutation2(num,sizeof(num)/sizeof(int));
return 0;
}
//这是我写的代码//给出一个字符串的所有排列,重复项过滤掉
int flags[256];
//char max,min;
//destination, 排序后的字符串
//insrPos,字母插入位置
//len, 待排序字符串总长度
void allRank(int* destination,int insrPos,char max, char min,int len)
{
// static int count;
int i = 0;
//recursion finished
if(insrPos == len)
{
//printf("%d:%s,len = %d, insrPos = %d\n",++count,destination, len, insrPos);
//printf("%s\n",destination);
for (i=0;i<len;i++)
printf("%d ",destination[i]);
printf("\n");
return ;
}
i = min;
while(i <= max)
{
//字母exists
if( flags[i])
{
destination[insrPos] = i;
flags[i] -= 1;
allRank(destination,insrPos+1,max,min,len);
flags[i] += 1;
}
i++;
}
}
void allArray(int* source, int len)
{
int i;
int max, min;
int p[101] = {0};
for(i = 0; i < 256; i++)
{
flags[i] = 0;
}
max = min = flags[0];
for(i = 0; i < len; i++)
{
flags[source[i]] +=1;
if(max < source[i])
max = source[i];
else if(min > source[i])
min = source[i];
}
allRank(p,0,max,min,len);
}
int TADICAN()
{
int num[]={2,2,3};
allArray(num,sizeof(num)/sizeof(int));
return 0;
}
inline int Swap2(int& a, int& b)
{// 交换a和b
// 如果 a、b 不是同一个成员,但是值相等,就不交换
if ( (&a != &b) && (a == b)) // C 语法都快忘了,不知道对不对
return 0;
int temp = a;
a = b;
b = temp;
return 1;
}
void Perm2(int list[], int k, int m)
{ //生成list [k:m ]的所有排列方式
int i;
if (k == m) {//输出一个排列方式
for (i = 0; i <= m; i++)
printf("%d ",list[i]);
putchar('\n');
}
else // list[k:m ]有多个排列方式
// 递归地产生这些排列方式
for (i=k; i <= m; i++) {
if (Swap2(list[k], list[i])) {
Perm (list, k+1, m);
Swap2 (list [k], list [i]);
}
}
}
int tiger_zhao() //可重复,但正确
{
int s[]={2,2,3};
Perm2(s, 0, 2);
return 0;
}
//全排列吗?递归实现。没有考虑非递减。
void swap3(int& a, int& b)
{
int temp;
temp=a;
a=b;
b=temp;
}
void permStr(int str[],int i,int len)
{
int j;
if( i==len-1)
{
int j;
for (j=0;j<len;j++)
{
printf("%d ",str[j]);
}
printf("\n");
}
else
{
for( j=i;j < len;j++)
{
swap3(str[i],str[j]);
permStr(str,i+1,len);
swap3(str[i],str[j]);
}
}
}
void hairetz()
{
int str[]={2,2,3};
permStr(str,0,sizeof(str)/sizeof(int));
}
int main(int argc, char* argv[])
{
//dobear_0922(); //没有去掉重复元素
//currenttt(); //正确,代码较复杂,使用到了全局变量
//tailzhou(); //正确,递归归本,代码较简单,不需辅助空间
//tailzhou2(); //正确,非递归归本,代码较简单,不需辅助空间
//TADICAN(); //正确,代码较复杂,使用到了全局变量
//tiger_zhao(); //错误,有重复的排列
hairetz(); //错误,有重复的元素
return 0;
}
#include <stdio.h>
inline boolean Swap(char& a, char& b)
{// 交换a和b
// 如果 a、b 不是同一个成员,但是值相等,就不交换
if ((&a <> &b) && (a == b)) // C 语法都快忘了,不知道对不对
return false;
char temp = a;
a = b;
b = temp;
return true;
}
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 (Swap(list[k], list[i])) {
Perm (list, k+1, m);
Swap (list [k], list [i]);
}
}
}
int main()
{
char s[]="121";
Perm(s, 0, 2);
return 0;
}
void permutation(int *a,int n)
{
int i,j,k,t;
while(1)
{
print_permutation(a,n);
for (i=n-1;i>0 && a[i]<=a[i-1];i-- ) ;
if (i==0) return;
for (j=n-1;j>0 && a[j]<=a[i-1];j-- ) ;
swap(a,i-1,j);
for (j=i,k=n-1;j<k;j++,k--) swap(a,j,k);
}
}
/*
顾名思义,这种方法的思想就是将所有n元排列按“字典顺序”排成队,以12…n为第一个排列,排序的规则,也就是由一个排列(p)=(p1p2…pn)直接生成下一个排列的算法可归结为
(1) 求满足关系式p[k-1]<p[k] 的k的最大值,设为i,
(2) 求满足关系式p[i-1]<p[k] 的k的最大值,设为j,
(3) p[i-1] 与p[j] 互换位置得
(q)=(q1 q2 … qn);
(4) (q)=(q1 q2 … qi-1 qi qi+1 … qn)中qi qi+1 … qn部分的顺序逆转,得
q1 q2 … qi-1 qn…qi+1 qi
这便是所求的下一个排列。
*/
#include <stdio.h>
void print_permutation(int *a,int n)
{
int i;
for (i=0;i<n ;i++ ) printf("%3d ",a[i]);
printf("\n");
}
void swap(int *a,int i,int j)
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
void permutation(int *a,int n)
{
int i,j,k,t;
print_permutation(a,n);
for (i=n-1;i>0 && a[i]<=a[i-1];i-- ) ;
if (i==0) return;
for (j=n-1;j>0 && a[j]<=a[i-1];j-- ) ;
swap(a,i-1,j);
for (j=i,k=n-1;j<k;j++,k--) swap(a,j,k);
permutation(a,n);
}
int main()
{
int num[]={2,3,3,4,4};
permutation(num,sizeof(num)/sizeof(int));
return 0;
}
#include <iostream>
using namespace std;
#define N 10
int input[N];
bool is_used[N];
int result[N];
int n;
int cmp(const void *a1, const void *a2)
{
int t1 = *(int*)a1;
int t2 = *(int*)a2;
return t1 - t2;
}
void init(int n)
{
for (int i = 0; i < n; i++)
{
is_used[i] = false;
}
}
int test(int k)
{
int ret = 0;
if (k == n)
{
for (int i = 0; i < n; i++)
{
cout << result[i] << ' ';
}
cout << endl;
return 1;
}
for (int i = 0; i < n; i++)
{
if (is_used[i] == false)
{
if (i == 0)
{
is_used[i] = true;
result[k] = input[i];
ret += test(k + 1);
is_used[i] = false;
}
else
{
if (input[i - 1] != input[i])
{
is_used[i] = true;
result[k] = input[i];
ret += test(k + 1);
is_used[i] = false;
}
if (input[i - 1] == input[i] && is_used[i - 1] == true)
{
is_used[i] = true;
result[k] = input[i];
ret += test(k + 1);
is_used[i] = false;
}
}
}
}
return ret;
}
int main()
{
cin >> n;
init(n);
for (int i = 0; i < n; i++)
{
cin >> input[i];
}
cout << endl;
qsort(input, n, sizeof(int), cmp);
int num = test(0);
cout << num << endl;
system("pause");
return 0;
}
#include <stdio.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++) {
Swap (list[k], list[i]);
Perm (list, k+1, m);
Swap (list [k], list [i]);
}
}
int main()
{
char s[]="123";
Perm(s, 0, 2);
return 0;
}