Today, a student asked me some questions about big data, one of which is representative, such as determining whether a URL is in the Set, 10 URLs, and whether a URL is in the set, for example ~ 1 million consecutive unordered numbers, random n numbers, and so on. This type of problem requires a large data set, and each data unit is small, such as an int. To a large extent, this type of problem can be done using bitmap or bloomfilter. The basic idea is to open up a large memory, and then use eight bits in a byte to implement tag elements by bit. Because the address space is continuous, so the search is O (1. What needs to be said here is that the determination of bloomfilter does not belong to a set. In theory, there is a misjudgment. If 100% data is required to be correct, do not use bloomfilter.
As the name suggests, bitmap is a memory. Memory is a continuous bitmap. Each bit passes through 0 and 1 to indicate whether or not an element exists. For example, a number whose number is n corresponds to bitmap, which is the byte n/8, and is mapped to the 01 bits n % 8. Therefore, by detecting the corresponding bit, you can know that the data is not in the Set and the data is correct. Go directly Code :
[CPP]
# Include <cstdlib>
# Include <iostream>
# Include <algorithm>
# Include <vector>
# Include <stddef. h>
# Include <memory. h>
# Define bytes 12500
Int main ()
{
Srand (unsigned INT) Time (null ));
Size_t total_numbers = 100000;
Typedef STD: vector <int> setcontainer;
Typedef STD: vector <int >:: iterator setiterator;
Setcontainer numbers;
Numbers. Reserve (total_numbers );
Int R1 = rand () % total_numbers;
Int r2 = R1 + 1000;
// Generate total_numbers-2 numbers
For (INT I = 0; I! = Total_numbers; ++ I ){
If (I! = R1 & I! = R2)
Numbers. push_back (I );
}
STD: cout <"[" <numbers. Size () <"] insert OK ";
STD: cin. Get ();
// Shuffle
STD: random_shuffle (numbers. Begin (), numbers. End ());
Unsigned char * bitmap = (unsigned char *) malloc (bytes );
Memset (bitmap, 0, bytes );
For (setiterator itr = numbers. Begin (); itr! = Numbers. End (); ++ itr ){
Ptrdiff_t forward = (* itr)/8;
Size_t offset = (* itr) % 8;
Bitmap [forward] | = (0x80ul> offset );
}
STD: cout <"bitmap build OK ";
STD: cin. Get ();
For (Int J = 0; J! = Bytes; ++ J ){
If (Bitmap [J]! = 0xff ){
STD: cout <"find ";
Unsigned long num = J * 8;
Unsigned char check = bitmap [J];
Unsigned char bit = 0;
While (bit! = 8 ){
If (0 = (check & (0x80ul> bit )))
STD: cout <"[" <(Num + bit) <"]";
Bit ++;
}
STD: cout <STD: Endl;
}
}
STD: cout <"done ";
STD: cin. Get ();
Free (Bitmap );
Return 0;
}
Bloomfilter is a binary vector data structure proposed by Howard bloom in 1970. It is suitable for reading more data than bitmap:
1. initialize a large memory to store the 01 flag:
2. By using N hash functions (n = 3), hash the same value multiple times and map it to bloomfilter like bitmap,
3. During the detection, the system also uses N hashes to find the ing bits, and maintains the inclusion relationship at the detection if every bit of the ing is 1. As mentioned above, bloomfilter may have misjudgment. The probability of misjudgment depends on the number of hash functions, the probability of hash function collision, and the memory size opened by bloomfilter. An appropriate value is required for the number of hash functions, which may cause efficiency problems. If the number of hash functions is large, it may lead to incorrect judgment. The theory is 5 ~ Between 10, 3 ~ is used in the project ~ Five, depending on your needs.
Code:
[CPP]
# Include <cstdlib>
# Include <cstdio>
# Include <iostream>
# Include <algorithm>
# Include <vector>
# Include <stddef. h>
# Include <memory. h>
# Define bloom (1024ul * 1024ul * 1024ul) // 1g
# Define hash_result 3
Typedef unsigned char bloomfilter;
Typedef struct _ hash_result {
Size_t N; // how many results
Size_t result [0];
} Hashresult;
/* Brian kernighan & Dennis Ritchie hashfunction, used in Java */
Size_t bkdr_hash (const char * Str)
{
Register size_t hash = 0;
While (size_t CH = (size_t) * STR ++ ){
Hash = hash * 131 + CH;
}
Return hash;
}
/* UNIX system hashfunction, also used in Microsoft's hash_map */
Size_t fnv_hash (const char * Str)
{
If (! * Str)
Return 0;
Register size_t hash = 2166136261;
While (size_t CH = (size_t) * STR ++ ){
Hash * = 16777619;
Hash ^ = CH;
}
Return hash;
}
/* Donald knuth hashfunction, presented in book <art of computer programming> */
Size_t dek_hash (const char * Str)
{
If (! * Str)
Return 0;
Register size_t hash = 1315423911;
While (size_t CH = (size_t) * STR ++ ){
Hash = (hash <5) ^ (hash> 27) ^ ch;
}
Return hash;
}
Typedef size_t (* hash_func) (const char *);
Hash_func hash [] = {
Bkdr_hash, fnv_hash, dek_hash
};
Void bloom_filter_mark (bloomfilter * BF, const char * V)
{
Hashresult * hR = (hashresult *) calloc (1, sizeof (hashresult) + (sizeof (size_t) * hash_result ));
For (INT I = 0; I! = Hash_result; ++ I ){
HR-> result [I] = (hash [I] (V) % bloom;
// Set the binary bit to 1
BF [HR-> result [I]/8] | = 0x80ul> (HR-> result [I] % 8 );
// Printf ("** % lu | hash-% d [% lu] | offset [% x] \ n", hash [I] (V), I, HR-> result [I], BF [HR-> result [I]/8]);
}
Free (HR );
}
Bool bloom_filter_check (bloomfilter * BF, const char * V)
{
Hashresult * hR = (hashresult *) calloc (1, sizeof (hashresult) + (sizeof (size_t) * hash_result ));
Size_t in = hash_result;
For (INT I = 0; I! = Hash_result; ++ I ){
HR-> result [I] = hash [I] (v) % bloom;
// Printf ("** % lu | % x \ n", HR-> result [I], BF [HR-> result [I]/8]);
// Check this bit is "1" or not
If (Bf [HR-> result [I]/8] & (0x80ul> (HR-> result [I] % 8 )))
In --;
}
Free (HR );
Return in = 0;
}
Int main ()
{
// STD: cout <bkdr_hash ("0") <STD: Endl;
// STD: cout <dek_hash ("0") <STD: Endl;
// STD: cout <fnv_hash ("0") <STD: Endl;
Bloomfilter * bloom = new (STD: nothrow) bloomfilter [bloom];
If (null = Bloom)
Printf ("no space to build bloomfilter \ n"), exit (0 );
Printf ("bloomfilter calloc memory OK \ n ");
For (INT I = 0; I! = 1000000; I ++ ){
Char Buf [16] = {0 };
Sprintf (BUF, "% d", I );
Bloom_filter_mark (Bloom, Buf );
}
Printf ("bloomfilter build OK \ n ");
For (INT I = 999995; I! = 1000010; I ++ ){
Char Buf [16] = {0 };
Sprintf (BUF, "% d", I );
If (bloom_filter_check (Bloom, Buf ))
Printf ("[found] % d \ n", I );
}
Delete bloom;
Return 0;
}
Transferred fromHttp://www.2cto.com/kf/201209/157387.html