JAVA Bitset應用總結

/** * 演示java.util.BitSet類的使用 * BitSet類表示自動增長位集合 * @author Sking */ package bitset; import java.util.BitSet; public class BitSetAPITest { public static void main(String[] args){ //BitSet的構造函數 BitSet b1=new BitSet(); BitSet b2=new BitSet(20); //set方法演示 for(int i=3;i<20;i+=3) b1.set(i); System.out.println(b1.toString());//{3, 6, 9, 12, 15, 18} for(int i=2;i<15;i+=2) b1.set(i, false); System.out.println(b1.toString());//{3, 9, 15, 18} b2.set(5, 10); System.out.println(b2.toString());//{5, 6, 7, 8, 9} b2.set(8,14,false); System.out.println(b2.toString());//{5, 6, 7} //flip方法演示 b2.flip(10,15); System.out.println(b2.toString());//{5, 6, 7, 10, 11, 12, 13, 14} b1.flip(15); System.out.println(b1.toString());//{3, 9, 18} //clear方法演示 b2.clear(10); System.out.println(b2.toString());//{5, 6, 7, 11, 12, 13, 14} b2.clear(6, 9); System.out.println(b2.toString());//{5, 11, 12, 13, 14} b2.clear(); System.out.println(b2.toString());//{} //get方法演示 boolean get9=b1.get(9); System.out.println(get9);//true BitSet b3=b1.get(3,10); System.out.println(b3.toString());//{0, 6} b1.set(7,13); b2.set(9,16); System.out.println(b1.toString());//{3, 7, 8, 9, 10, 11, 12, 18} System.out.println(b2.toString());//{9, 10, 11, 12, 13, 14, 15} //位集操作 b1.and(b2); System.out.println(b1.toString());//{9, 10, 11, 12} b2.xor(b1); System.out.println(b2.toString());//{13, 14, 15} b1.or(b2); System.out.println(b1.toString());//{9, 10, 11, 12, 13, 14, 15} b3.set(13,15); b2.andNot(b3); System.out.println(b2.toString());//{15} //設置位操作 System.out.println(b1.cardinality());//7 System.out.println(b2.isEmpty());//false b2.clear(); System.out.println(b2.isEmpty());//true System.out.println(b1.intersects(b3));//true //大小操作 System.out.println(b1.size());//64 System.out.println(b1.length());//16=15+1 //查找 System.out.println(b1.nextSetBit(9));//9 System.out.println(b1.nextClearBit(9));//16 System.out.println(b1.previousSetBit(20));//15 System.out.println(b1.previousClearBit(15));//8 //類型轉化操作 //byte[] b=b1.toByteArray(); //long[] l=b1.toLongArray(); } }

 
	/**
	 * 藉助BitSet使用篩選法查找指定範圍內的素數
	 * @param limit 最大正數
	 */
	public static void searchPrime(int limit){
		BitSet bs=new BitSet(limit+1);
		//約定:不是素數的在BitSet中將相應的位設置爲true
		int size=bs.size();
		bs.set(1);
		for(int i=4;i<size;i+=2)
			bs.set(i);//偶數均不是素數
		int finalBit=(int)Math.sqrt(size);
		for(int i=2;i<finalBit;i++)
				for(int j=2*i;j<size;j+=i)
					bs.set(j);
		int cout=0;
		for(int i=1;i<size;i++){
			if(!bs.get(i)){
				System.out.printf("%5d",i);
				if(++cout==0)
					System.out.println();
			}
		}
		System.out.println();
	}
	
	/**
	 * 判斷一個字符串使用了哪些字符,輸出格式爲[字符序列]
	 * @param s 指定的字符串
	 * @return 字符串使用的字符序列
	 */
	public static String whichChars(String s){
		BitSet bs=new BitSet();
		//字符被使用,則將索引等於字符ASCII值的位置設置爲true
		for(int i=0;i<s.length();i++)
			bs.set(s.charAt(i));
		StringBuffer sb=new StringBuffer();
		//輸出格式化
		sb.append('[');
		int len=bs.length();
		for(int i=0;i<len;i++)
			if(bs.get(i))
				sb.append((char)i);
		sb.append(']');
		return sb.toString();	
	}


 

/**
 * 多哈希函數映射的快速查找算法,使用BitSet實現
 * 應用在一些需要快速判斷某個元素是否屬於集合,
 * 但是並不嚴格要求100%正確的場合,實現大數據處理。
 * 應用場景包括:爬蟲中url的存儲。
 * 
Bloom Filter實現原理:
1.創建BitSet,所有位初始爲false,選擇k個哈希函數
2.將插入值運用k個哈希函數映射到k個二進制位,將其設爲true
3.如果k個二進制爲中有一個有false,則表示原紀錄未被加入過;
    如果k個二進制位都有true,則”認爲“原紀錄已被紀錄過,
    但是實際上不能100%確定(false positive)。
 * @author Sking
 */
package bitset;

import java.util.BitSet;

public class BloomFilter {
	/* BitSet初始分配2^24個bit */
	private static final int DEFAULT_SIZE = 1 << 25;
	/* 不同哈希函數的種子,一般應取質數 */
	private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37, 61 };
	private BitSet bits = new BitSet(DEFAULT_SIZE);
	/* 哈希函數對象 */
	private SimpleHash[] func = new SimpleHash[seeds.length];

	public BloomFilter() {
		for (int i = 0; i < seeds.length; i++) {
			func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
		}
	}

	// 將字符串標記到bits中
	public void add(String value) {
		for (SimpleHash f : func) {
			bits.set(f.hash(value), true);
		}
	}

	// 判斷字符串是否已經被bits標記
	public boolean contains(String value) {
		if (value == null) {
			return false;
		}
		boolean ret = true;
		for (SimpleHash f : func) {
	//如果出現一次的bits.get(f.hash(value))爲false,則原紀錄未被加入過
			ret = ret && bits.get(f.hash(value));
		}
		return ret;
	}

	/* 哈希函數類,可修改哈希函數,實現更好的優化 */
	public static class SimpleHash {
		private int cap;//容量
		private int seed;//種子

		public SimpleHash(int cap, int seed) {
			this.cap = cap;
			this.seed = seed;
		}
		// hash函數,採用簡單的加權和hash
		public int hash(String value) {
			int result = 0;
			int len = value.length();
			for (int i = 0; i < len; i++) {
				result = seed * result + value.charAt(i);
			}
			return (cap - 1) & result;//截取加權的低log2(cap)位
		}
	}
}


java.lang.Object

  java.util.BitSet

public class BitSet extends Object implements CloneableSerializable

——按需增長的位向量。默認情況下,set 中所有位的初始值都是 false。每個

    bitset都包含若干設置位(值爲true的位)。

 

   構造函數

BitSet()  

BitSet(int nbits)

普通方法

——1.清除位

void clear()

void clear(int bitIndex)

void clear(int fromIndex,int toIndex)
——分別將全部位指定區間內的位(不包括toIndex指定位設置爲false

——2.翻轉位

void flip(int bitIndex)

void flip(int fromIndex,int toIndex)

——將指定位指定區間內的位翻轉

——3.設置位

void set(int bitIndex)

void set(int bitIndex,boolean value)

void set(int fromIndex,int toIndex)

void set(int fromIndex,int toIndex,boolean value)

——將指定位指定區間內的位設置爲指定boolean值,沒有指定則爲true

——4.獲取位

boolean get(int bitIndex)

BitSet get(int fromIndex,int toIndex)

——獲取指定位指定區間內的位集

int nextSetBit|previousSetBit(int fromIndex)

——從指定位開始查找下一個|前一個true的位索引,沒有返回-1

int nextClearBit|previousClearBit(int fromIndex)

——從指定位開始查找下一個|前一個false的位索引,沒有返回-1

——5.位集操作《改變的是當前BitSet,而不是參數BitSet

void and(BitSet set) //

void or(BitSet set)  //

void xor(BitSet set) //異或

void andNot(BitSet set) //不是與非操作

——清除此 BitSet 中所有的位,其相應的位在指定的 BitSet 中已設置。 

——6.設置位操作

int cardinality()

——位集中設置位的個數

boolean isEmpty()

——如果位集中沒有設置位,則返回true

boolean intersects(BitSet set)

——如果兩個位集中存在同一個位置均爲設置位則返回true

——7.大小操作

int size()    //實際分配空間

int length()  //邏輯大小,最高設置位的索引加1

——8.打印操作

String toString()

——格式:{設置爲true的位索引列表,用,分隔}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章