集合包含關系的快速算法


#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?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM