1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Web; 8 9 namespace ConsoleApplication2 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 BloomFilter<string> bf = new BloomFilter<string>(20, 3); 16 17 bf.Add("testing"); 18 bf.Add("nottesting"); 19 bf.Add("testingagain"); 20 21 Console.WriteLine(bf.Contains("badstring")); // False 22 Console.WriteLine(bf.Contains("testing")); // True 23 24 List<string> testItems = new List<string>() { "badstring", "testing", "test" }; 25 26 Console.WriteLine(bf.ContainsAll(testItems)); // False 27 Console.WriteLine(bf.ContainsAny(testItems)); // True 28 29 //误检率: 0.040894188143892 30 Console.WriteLine("False Positive Probability: " + bf.FalsePositiveProbability()); 31 32 Console.ReadKey(); 33 34 35 } 36 37 /// <summary> 38 /// 一个布隆过滤器是一个空间有效的概率数据结构 39 /// 用于测试一个元素是否是一个集合的成员。误检率是可能的,但漏检率是不存在的。元素可以被添加到集合,但不能从集合删除。 40 /// </summary> 41 /// <typeparam name="Type">泛型数据类型</typeparam> 42 public class BloomFilter<T> 43 { 44 Random _random; 45 int _bitSize, _numberOfHashes, _setSize; 46 BitArray _bitArray; 47 48 #region Constructors 49 /// <summary> 50 /// 初始化bloom滤波器并设置hash散列的最佳数目 51 /// </summary> 52 /// <param name="bitSize">布隆过滤器的大小(m)</param> 53 /// <param name="setSize">集合的大小 (n)</param> 54 public BloomFilter(int bitSize, int setSize) 55 { 56 _bitSize = bitSize; 57 _bitArray = new BitArray(bitSize); 58 _setSize = setSize; 59 _numberOfHashes = OptimalNumberOfHashes(_bitSize, _setSize); 60 } 61 62 //<param name="numberOfHashes">hash散列函数的数量(k)</param> 63 public BloomFilter(int bitSize, int setSize, int numberOfHashes) 64 { 65 _bitSize = bitSize; 66 _bitArray = new BitArray(bitSize); 67 _setSize = setSize; 68 _numberOfHashes = numberOfHashes; 69 } 70 #endregion 71 72 #region 属性 73 public int NumberOfHashes 74 { 75 set 76 { 77 _numberOfHashes = value; 78 } 79 get 80 { 81 return _numberOfHashes; 82 } 83 } 84 public int SetSize 85 { 86 set 87 { 88 _setSize = value; 89 } 90 get 91 { 92 return _setSize; 93 } 94 } 95 public int BitSize 96 { 97 set 98 { 99 _bitSize = value; 100 } 101 get 102 { 103 return _bitSize; 104 } 105 } 106 #endregion 107 108 #region 公共方法 109 public void Add(T item) 110 { 111 _random = new Random(Hash(item)); 112 113 for (int i = 0; i < _numberOfHashes; i++) 114 _bitArray[_random.Next(_bitSize)] = true; 115 } 116 public bool Contains(T item) 117 { 118 _random = new Random(Hash(item)); 119 120 for (int i = 0; i < _numberOfHashes; i++) 121 { 122 if (!_bitArray[_random.Next(_bitSize)]) 123 return false; 124 } 125 return true; 126 } 127 128 //检查列表中的任何项是否可能是在集合。 129 //如果布隆过滤器包含列表中的任何一项,返回真 130 public bool ContainsAny(List<T> items) 131 { 132 foreach (T item in items) 133 { 134 if (Contains(item)) 135 return true; 136 } 137 return false; 138 } 139 140 //检查列表中的所有项目是否都在集合。 141 public bool ContainsAll(List<T> items) 142 { 143 foreach (T item in items) 144 { 145 if (!Contains(item)) 146 return false; 147 } 148 149 return true; 150 } 151 152 /// <summary> 153 /// 计算遇到误检率的概率。 154 /// </summary> 155 /// <returns>Probability of a false positive</returns> 156 public double FalsePositiveProbability() 157 { 158 return Math.Pow((1 - Math.Exp(-_numberOfHashes * _setSize / (double)_bitSize)), _numberOfHashes); 159 } 160 #endregion 161 162 #region 私有方法 163 private int Hash(T item) { 164 return item.GetHashCode(); 165 } 166 167 //计算基于布隆过滤器散列的最佳数量 168 private int OptimalNumberOfHashes(int bitSize, int setSize) 169 { 170 return (int)Math.Ceiling((bitSize / setSize) * Math.Log(2.0)); 171 } 172 #endregion 173 } 174 } 175 176 177 }