#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號元素。
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
這么一來要判斷要簡單多了,只需要
2 unsigned dst //代表較少元素數組的編碼
3 if (src & dst == dst)
4 return true;
5
6 return false;
但是且慢,如何將1 2 3 4等元素存入 src 之類變量?
So, 手工加工的 table登場
2 0x00000001, 0x00000002, 0x00000004, 0x00000008,
3 0x00000010, 0x00000020, 0x00000040, 0x00000080,
4 0x00000100, 0x00000200, 0x00000400, 0x00000800,
5 0x00001000, 0x00002000, 0x00004000, 0x00008000,
6 0x00010000, 0x00020000, 0x00040000, 0x00080000,
7 0x00100000, 0x00200000, 0x00400000, 0x00800000,
8 0x01000000, 0x02000000, 0x04000000, 0x08000000,
9 0x10000000, 0x20000000, 0x40000000, 0x80000000
10 };
只需要每數組掃描一遍即可實現目標。
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
可按下圖來考慮
0 1
. .
. .
. .
31 32
32 -- 0 1
. .
. .
. .
63 -- 31 32
再構造數組
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.
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 == 0) return - 1;
25
26 for (normalInt m= 1; m<subset; m++ ){
27 if (index[m] < 0) continue;
28
29 for(normalInt n=m+ 1; n<subset+ 1; n++){
30 if(index[n] < 0) continue;
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 == false) break;
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?