forked from HIT-SCIR/ltp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tinybitset.hpp
129 lines (114 loc) · 2.95 KB
/
tinybitset.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef __LTP_UTILS_BITSET__
#define __LTP_UTILS_BITSET__
#include <iostream>
#include <string.h>
#include <vector>
namespace ltp {
namespace utility {
const int kBucketSize = int( sizeof(unsigned) ) * 8;
const int kBucketCap = 4;
// A parallize method for calculate number of bits in a number. Adopt this from
// http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
const int kN1 = (kBucketSize - 1) - (((kBucketSize - 1) >> 1) & 0x55555555);
const int kN2 = (kN1 & 0x33333333) + ((kN1 >> 2) & 0x33333333);
const int kN = (((kN2 + (kN2 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;;
struct Bitset {
private:
bool emptyflag;
unsigned bits[kBucketCap];
public:
// Constructor
Bitset() {
memset(bits,0,sizeof(bits));
emptyflag = 1;
}
Bitset(int val) {
memset(bits,0,sizeof(bits));
emptyflag = 1;
set(val);
}
inline bool empty() const {
return emptyflag;
}
inline void allsetones() {
memset(bits, 0xff, sizeof(bits));
emptyflag = 1;
}
inline bool set(int val) {
int bucket_index = val >> kN;
int bucket_off = val & (kBucketSize - 1);
if (bucket_index<0 || bucket_index >= kBucketCap){
return false;
}
bits[bucket_index] |= (1<<bucket_off);
emptyflag = 0;
return true;
}
/**
* Merge two Bitset together.
*
* e.g.:
*
* Bitset mask1(0x02), mask2(0x03);
* mask1.merge(mask2);
* std::cout << mask1.bitset[0] << std::endl; // => 3
*
* @param[in] other The other bitset
* @return bool ?
*/
inline bool merge(const Bitset & other) {
for(int i = 0; i < kBucketCap; ++ i) {
bits[i] |= (other.bits[i]);
}
emptyflag &= (other.emptyflag);
return true;
}
/**
* Get the ith bit of the bitset
*
* e.g.:
*
* Bitset mask1(0x02);
* std::cout << mask1.get(0) << std::endl; // => false
* std::cout << mask1.get(1) << std::endl; // => true
*
* @param[in] val Specify ith bit
* @return bool Return true on ith bit is true, otherwise false.
*/
inline bool get(int val) const {
int bucket_index = val >> kN;
int bucket_off = val & (kBucketSize - 1);
if (bucket_index<0 || bucket_index >= kBucketCap){
return false;
}
if(bits[bucket_index] & (1<<bucket_off)) {
return true;
}
return false;
}
inline std::vector<int> getbitones() const{
std::vector<int> ones;
unsigned x,y;
int curbit;
for(int i = 0; i < kBucketCap; ++ i){
x = bits[i];
while(x != 0){
y = x&(x^(x-1));
curbit = -1;
while(y != 0){
y >>= 1;
curbit++;
}//end while y!=0
if(curbit != -1){
curbit += (kBucketSize * i);
ones.push_back(curbit);
}//end if
x = x&(x-1);
}//end while x!=0
}//end for
return ones;
}
};
} // end for namespace utility
} // end for namespace ltp
#endif // end for __LTP_UTILS_BITSET__