用C去操作集合,有时候觉得十分的麻烦,不过,集合又一定要用。苦思了一些日子,当集合遇到了二进制,也当二进制到了位运算。这个就很好解决。建立这样的一个模型,当集合A有元素a,就用1在a相应的位表示出来,否则就为0 。
一个例子:A={a,b,c} --------7(111) , A有一字集A1={a,c}-------------5(101)
就这样表示。
集合与二进制有一个很思意的相同点,n个元素的集合有2^n个子集;n位的二进制有2^n个表示方法,好吧,让他们对应起来吧。
对于集合B={a,b},看下面:
+--------+--------+--------+
| 集合 | 二进制| 整数 |
+--------+--------+--------+
| 空集 | 00 | 0 |
+--------+--------+--------+
| {a} | 01 | 1 |
+--------+--------+--------+
| {b} | 10 | 2 |
+--------+--------+--------+
| {a,b} | 11 | 3 |
+--------+--------+--------+
就这样了。对于集合的操作也就是相应的操作了,写一个C代码看得具体一点。
#include
void bin_to_set(unsigned int x , char e[]){
int i = 0,f = 0 ;
printf("{") ;
while(x > 0){
if((x & 1) == 1) {
if(f == 0) {printf("%c",e[i]) ; f = 1 ;}
else printf(",%c",e[i]) ;
}
++i ;
x >>= 1 ;
}
printf("}") ;
}
unsigned int U(unsigned int x1 ,unsigned int x2){//并
return ( x1 | x2 ) ;
}
unsigned int C(unsigned int x1 ,unsigned int x2){//交
return ( x1 & x2 ) ;
}
unsigned int N(unsigned int x,int n){//非
return (((1<< n) -1) ^ x) ;
}
int E(unsigned int x1 ,unsigned int x2){//x2是否包括x1
return ( (x1 | x2) == x2 ) ;
}
void hind_set( char *c,int n){
int m = 1 << n ;
int i ;
for(i = 0 ;i < m ; ++i){
bin_to_set(i,c) ;
printf("\n") ;
}
}
int main(){
char c[] = {'a','b','c'} ;
printf("{a,b,c}的幂集:\n") ;
hind_set(c,3) ;
unsigned x1 = 5 ;//{a,c}
unsigned x2 = 3 ;//{a,b}
unsigned x = 7 ;//{a,b,c}
printf("{a,c}与{a,b}并:") ;
bin_to_set(U(x1,x2),c) ;
printf("\n{a,c}与{a,b}交:") ;
bin_to_set(C(x1,x2),c) ;
printf("\n{a,c}的非:") ;
bin_to_set(N(x1,3),c) ;
printf("\n{a,c}是{a,b}的子集吗? %d",E(x1,x2)) ;
printf("\n{a,c}是{a,b,c}的子集吗? %d",E(x1,x)) ;
return 0 ;
}
结果: