集合包含关系的快速算法

#1 每行数据代表一个集合,如何判断集合的包含关系? -- 集合的数据仅在有限范围内。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23       a --24个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24     b --24个元素

最容易想到的是蛮力运算,计算前还应该知道谁元素多,对吧?不过还好,我耍了个花招,在读取数据时已经把数组元素数目存入数组第0号元素。

1 for each element x in a
2     if (!setContain(b , x))
3        return false;
4 
5 return true;    

#2 数据在31以内,考虑用无符号数编码数组
例如 1 2 3 4 用 0x00000000 00000000 00000000 00001111编码,也就是1用第一个bit,2用第二个bit,依此类推...
但是数据里面有0,也好说,0用第一个bit,1用第二个bit,依此类推...
这样1 2 3 4 最终形式 0x00000000 00000000 00000000 00011110
这么一来要判断要简单多了,只需要

1 unsigned src //代表较多元素数组的编码
2 unsigned dst //代表较少元素数组的编码
3 if (src & dst == dst)
4     return true;
5 
6 return false;

但是且慢,如何将1 2 3 4等元素存入 src 之类变量?
So, 手工加工的 table登场

 1     unsigned int table[32] = {
 2         0x000000010x000000020x000000040x00000008
 3         0x000000100x000000200x000000400x00000080,
 4         0x000001000x000002000x000004000x00000800
 5         0x000010000x000020000x000040000x00008000,
 6         0x000100000x000200000x000400000x00080000,
 7         0x001000000x002000000x004000000x00800000,
 8         0x010000000x020000000x040000000x08000000,
 9         0x100000000x200000000x400000000x80000000
10     };

只需要每数组扫描一遍即可实现目标。

1 src = 0;
2
3 for each element x in a
4     src = src + table[x];

问题基本解决。

#3 考虑如下数组:如何扩展至64位

25 26 27 28 29 30 31 32 33 34 35 36 37 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
26 27 28 29 30 31 32 33 34 35 36 37 38 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

可按下图来考虑

number      bit
0           1
.           .
.           .
.           .
31          32


32 -- 0     1
.           .
.           .
.           .
63 -- 31    32

再构造数组

1 int cache = {032};
2 unsigned int cacheManager[2][2];
3 //用二维数组维护两个数组的编码,每行编码一数组

方法如下,分别以16  , 63为例

运算 (16 & 0x00000020) >> 5 得出  0,  然后 16 - cache[0] 得出 16,   16 存入cacheManager[?][ 0 ]

运算 (63 & 0x00000020) >> 5 得出  1,  然后 63 - cache[1] 得出 31,    31存入cacheManager[?][ 1 ]

#4 实际代码,利用此方法,程序运行时间缩短到原来1/3.

 1 int fillCacheManager(normalInt * index, Element (* dt)[ElementNumber], unsigned int (*cm)[cacheLine], unsigned int * table){
 2     int element;
 3     int cache[2] = {0 , 32};
 4     int serial;
 5 
 6     for( normalInt m=1; m<=index[0]; m++ ){
 7         normalInt t = index[m];
 8         cm[t][0] = 0;
 9         cm[t][1] = 0;
10         for ( normalInt n=1; n<=dt[t][0]; n++  ){
11             element = dt[t][n];
12             serial = (element & 0x00000020) >>5;
13             element = element - cache[serial];
14             cm[t][serial] = cm[t][serial] + table[element] ;
15         }
16     }
17 
18     return 0;
19 }
20 
21 
22 int quickTableReducton(normalInt * index, Element (* dt)[ElementNumber], unsigned int (*cm)[cacheLine]){
23     normalInt subset = index[0];
24     if (subset == 0return -1;
25     
26     for (normalInt m=1; m<subset; m++ ){
27         if (index[m] < 0continue;
28         
29         for(normalInt n=m+1; n<subset+1; n++){
30             if(index[n] < 0continue;
31             if(n == m) continue;
32 
33             normalInt src = index[m];
34             normalInt dst = index[n];
35             normalInt QQ = dst;
36             bool swaped = false;
37             if (dt[src][0] < dt[dst][0]){
38                 swaped = true;
39                 QQ = src;
40             }
41 
42             if (  (cm[src][0] & cm[dst][0]) == cm[QQ][0]    &&   (cm[src][1] & cm[dst][1]) == cm[QQ][1]  ){
43                 int t = m;
44                 if (swaped) t = n;
45                 index[t] = -2
46                 index[0] = index[0]-1;
47                 if (swaped == falsebreak;            
48             }
49         }
50     }
51 
52     normalInt idx[indexCount];//indexOver
53     normalInt len=1;
54     for (normalInt m=1; index[m]!=indexOver; m++)//m<=index[0]
55         if (index[m] > -1){
56             idx[len] = index[m];
57             len++;
58         }
59 
60     for (normalInt m=1; m<len; m++) index[m] = idx[m];
61     index[len] = indexOver;
62 
63     return 0;
64 }

#5 STL bitset : better choice?

posted @ 2012-10-05 22:18  simcity  阅读(3650)  评论(0编辑  收藏  举报