您的位置:首页 > 编程语言 > C语言/C++

排列组合与集合的C语言实现相关

2017-02-02 21:37 609 查看
本文借鉴于《挑战程序设计竞赛》第二版P156到P157页的内容自己实现

1:枚举{0,1,~,n-1}所包含的所有子集的方法

#include <cstdio>
#include <iostream>
using namespace std;
int used[10000];
int main(){
int n;
cin >> n;
for(int i=0;i< 1 << n;i++){
memset(used,0,sizeof(used));
for(int j=0;j<n;j++) used[j] = i>>j & 1;
for(int j=0;j<n;j++) cout << used[j];
cout << endl;
}
return 0;
}


输入n=6我们可以得到如下的结果

000000
100000
010000
110000
001000
101000
011000
111000
000100
100100
010100
110100
001100
101100
011100
111100
000010
100010
010010
110010
001010
101010
011010
111010
000110
100110
010110
110110
001110
101110
011110
111110
000001
100001
010001
110001
001001
101001
011001
111001
000101
100101
010101
110101
001101
101101
011101
111101
000011
100011
010011
110011
001011
101011
011011
111011
000111
100111
010111
110111
001111
101111
011111
111111


2:枚举{0,1,~,n-1}所包含的所有大小为k的子集的方法即组合的实现

#include <cstdio>
#include <iostream>
using namespace std;
int k=3;
int used[10000];
int main(){
int n;
cin >> n;
int comb=(1<<k) -1;
while(comb < 1 << n){
//***********************************
//这里针对comb进行处理

4000
memset(used,0,sizeof(used));
for(int i=0;i<n;i++) used[i] = comb>>i & 1;
for(int i=0;i<n;i++) cout << used[i];
cout << endl;
//***********************************
int x = comb & -comb, y = comb + x;
comb = ((comb & ~y) / x >> 1) | y;
}
return 0;
}


输入n=6我们可以得到如下的结果

111000
110100
101100
011100
110010
101010
011010
100110
010110
001110
110001
101001
011001
100101
010101
001101
100011
010011
001011
000111


我们之后可以通过对used数组的操作来实现组合的效果

3:对集合{0,1,~,n-1}所有元素的全排列

#include <cstdio>
#include <iostream>
using namespace std;
int main(){
int n,a[100000];
cin >> n;
for(int i=0;i<n;i++) a[i]=i;
do{
for(int i=0;i<n;i++) cout << a[i];
cout << endl;
}while(next_permutation(a,a+n));
return 0;
}


输入n=4后得到

0123
0132
0213
0231
0312
0321
1023
1032
1203
1230
1302
1320
2013
2031
2103
2130
2301
2310
3012
3021
3102
3120
3201
3210


4:枚举集合n(二进制表示)所包含的所有子集的方法

#include <cstdio>
#include <iostream>
using namespace std;
int cal(int n){
int res=0;
while(n>0){
n/=10;
res++;
}
return res;
}
int main(){
int n,used[10000];;
cin >> n;
int len=cal(n);
int x=n;
do{
//***********************************************
//对子集的处理
memset(used,0,sizeof(used));
for(int i=0;i< (1 << len);i++) used[i] = x>>i & 1;
for(int i=0;i< (1 << len);i++) cout << used[i];
cout << endl;
//***********************************************
x=(x-1) & n;
}while(x != n);//处理完0后,会有-1&sup = sup;
return 0;
}


我们输入182即01101101可以得到它所有的子集有这样的规律即原来位上是0则所有的子集这里也全是0,原来位上是1则子集里这里不一定是1

这里写代码片01101101
00101101
01001101
00001101
01100101
00100101
01000101
00000101
01101001
00101001
01001001
00001001
01100001
00100001
01000001
00000001
01101100
00101100
01001100
00001100
01100100
00100100
01000100
00000100
01101000
00101000
01001000
00001000
01100000
00100000
01000000
00000000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: