位图可以用来排序,去重等。
但下面的位图法一般用来做正整数的排序,去重;若有负整数,可以再新建一个队列专门存负整数,先转成正整数去比较,存在这个负整数队列。
理解:
8位整数可以表示的最大十进制数值为99999999。如果每个数字对应于位图中一个bit位,那么存储8位整数大约需要99MB。因为1B=8bit,所以99Mbit折合成内存为99/8=12.375MB的内存,即可以只用12.375MB的内存表示所有的8位数电话号码的内容。
import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import com.google.common.collect.Lists; /** * 位图 */ public class Weitu { private static final int BITSPERWORD = 32;// 整数位数 private static final int SHIFT = 5; private static final byte MASK = 0x1F;//5位遮蔽 0B11111 private static final int N = 1000; private static int[] a = new int[1 + N / BITSPERWORD]; private static List<String> list = new ArrayList<String>(1 + N / BITSPERWORD); public static void main(String[] args) throws Exception { Weitu tu = new Weitu(); // tu.readFile("/Users/zj/aa1.txt"); tu.readFile("C:/Users/zj/Desktop/aa1.txt"); for (int i = 0; i < list.size(); i++) { tu.set(Integer.parseInt(list.get(i))); } List<Integer> resultList = Lists.newArrayList(); for (int i = 0, length = a.length; i < length; i++) { if (a[i] != 0) { for (int j = 0; j < (1 << SHIFT); j++) { if (((1 << j) & a[i]) != 0) { resultList.add(i * (1 << SHIFT) + j); } } } } for (Integer xx : resultList) { System.out.println(xx); } System.out.println((1 << 31) - 1); System.out.println(Integer.MAX_VALUE); } // 置a[i>>SHIFT]的第(i & MASK)位为1,也就是位数组的第i位为1 public void set(int i) { if (test(i)) { System.err.println(i); } a[i >> SHIFT] |= (1 << (i & MASK)); } // 置a[i>>SHIFT]的第(i & MASK)位为0,也就是位数组的第i位为0 public void clr(int i) { a[i >> SHIFT] &= ~(1 << (i & MASK)); } public int test11(int i) { return a[i >> SHIFT] & (1 << (i & MASK)); } // 测试位数组的第i位是否为1 (可以用作重复问题) public static boolean test(int i) { return (a[i >> SHIFT] & (1 << (i & MASK))) == (1 << (i & MASK)); } public void readFile(String filePath) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath))); String len; while ((len = br.readLine()) != null) { list.add(len); } br.close(); } }