03 MyBitSet

来源:互联网 发布:javascript官方文档 编辑:程序博客网 时间:2024/06/04 18:08

前言

这是一个之前的时候, 没事想模拟BitSet实现, 当时 记得是为了素数问题吧, 或者是其他的问题, 或者是无聊想起了, 这个只实现了BitSet的存取, 可以当做一个小例子没事的时候看看

就是涉及一些位操作, 移位操作
算法 和java.util.BitSet基本上是一致的, 不过这里的存储是使用int[] 来存放数据的

参考代码

/** * file name : Test18MyBitSet.java * created at : 8:15:46 PM May 23, 2015 * created by 970655147 */package com.hx.test03;public class Test19MyBitSet {    // BitSet的模拟    public static void main(String []args) {//      int size = 65;//      size = (size + 32 - 1) >> 5;//      Log.log(size);//      Log.log(Integer.toBinaryString(BitSet.HEAD_ONE_MASK));//      BitSet bs = new BitSet();//      Log.log(bs.toString());//      bs.set(3, true);//      Log.log(bs.toString());//      bs.set(32, true);//      Log.log(bs.toString());//      //      Log.log(bs.get(2));//      Log.log(bs.get(3));//      Log.log(bs.get(32));//      Log.log(bs.get(33));//      Log.log(bs.get(1, 10));//      //      int start = 3, end = 42;//      bs.set(start, end, true);//      Log.log(bs.get(start - 1, end + 1));//      BitSet bs = new BitSet(128);//      int start = 1, end = 74;//      bs.set(start, end, true);//      Log.log(bs.get(start - 1, end + 1));    }    // 一个模拟BitSet的类    static class BitSet {        // 默认的大小, int的位数, 获取int索引的mask, 获取int偏移的mask        // 0x00000000000000000000000000000001        // 0x11111111111111111111111111111111        // 0x10000000000000000000000000000000        private static int DEFAULT_SIZE = 64;        private static int INT_SIZE = 32;        private static int INT_RIGHT_SHIFT_SIZE = 5;        private static int INT_MASK = INT_SIZE - 1;        private static int ONE_MASK = 1;        private static int ALL_ONE_MASK = -1;        private static int HEAD_ONE_MASK = ONE_MASK << (INT_SIZE-1);        // 存放数据的int[], 以及容量        private int[] data;        private int capacity;        private int size;        // 初始化        public BitSet() {            this(DEFAULT_SIZE);        }        public BitSet(int capacity) {            int num = (capacity + INT_MASK) >> INT_RIGHT_SHIFT_SIZE;            data = new int[num];            this.capacity = capacity;            size = 0;        }        // 获取idx处的值        public boolean get(int idx) {            checkForIdx(idx);            int theKInt = intIdx(idx);            int theKBit = bitIdx(idx);            return get0(theKInt, theKBit);        }        // 获取start到end的值        public boolean[] get(int start, int end) {            checkForIdx(start);            checkForIdx(end);            int len = end - start;            checkForLen(len);            boolean[] res = new boolean[len];            int idx = 0;            for(int i=start; i<end; i++) {                int theKInt = intIdx(i);                int theKBit = bitIdx(i);                res[idx ++] = get0(theKInt, theKBit);            }            return res;        }        // 设置idx处的值        public void set(int idx, boolean val) {            checkForIdx(idx);            int theKInt = intIdx(idx);            int theKBit = bitIdx(idx);            set0(theKInt, theKBit, val);            if(val && (idx > size) ) {                size = idx;            }        }        // 获取start到end的值            // 如果start和end实在同一个int上面  设置start和end之间的值            // 否则先设置start之后的值, 在设置end之前的值  在设置其间的所有int        public void set(int start, int end, boolean val) {            checkForIdx(start);            checkForIdx(end);            int len = end - start;            checkForLen(len);            int theKInt01 = intIdx(start);            int theKBit01 = bitIdx(start);            int theKInt02 = intIdx(end);            int theKBit02 = bitIdx(end);            if(theKInt01 == theKInt02) {                int mask = ALL_ONE_MASK;                mask >>>= theKBit01;                mask <<= (theKBit01 + (INT_SIZE - theKBit02));                mask >>>= (INT_SIZE - theKBit02);                if(val) {                    data[theKInt01] |= mask;                } else {                    data[theKInt01] &= (~mask);                }            } else {                int startMask = ALL_ONE_MASK >>> theKBit01;                int endMask = ALL_ONE_MASK << (INT_SIZE - theKBit02);                startMask <<= theKBit01;                endMask >>>= (INT_SIZE - theKBit02);//              Log.log(Integer.toBinaryString(startMask));//              Log.log(Integer.toBinaryString(endMask));                if(val) {                    data[theKInt01] |= startMask;                    data[theKInt02] |= endMask;                    for(int i=theKInt01+1; i<theKInt02; i++) {                        data[i] |= ALL_ONE_MASK;                    }                } else {                    data[theKInt01] &= (~startMask);                    data[theKInt02] &= (~endMask);                    for(int i=theKInt01+1; i<theKInt02; i++) {                        data[i] &= (~ALL_ONE_MASK);                    }                }            }            if(val && (end > size) ) {                size = end;            }        }        // assistMethod        private boolean get0(int theKInt, int theKBit) {            return ( ((data[theKInt] >>> theKBit ) & ONE_MASK ) == 1 );        }        // assistMethod        private void set0(int theKInt, int theKBit, boolean val) {            if(val) {                data[theKInt] |= (ONE_MASK << theKBit);            } else {                data[theKInt] &= (~(ONE_MASK << theKBit));            }        }        // 获取        private int intIdx(int idx) {            return idx >>> INT_RIGHT_SHIFT_SIZE;        }        private int bitIdx(int idx) {            return idx & INT_MASK;        }        // 校验索引        private void checkForIdx(int idx) {            if(idx < 0 || idx >= capacity) {                throw new RuntimeException("check index exception...");            }        }        // 校验长度        private void checkForLen(int len) {            if(len <= 0) {                throw new RuntimeException("check index exception, endIndex must bigger than startIndex...");            }        }        // 当前BitSet的字符串表示        public String toString() {            // 1 0 ...  包含空格 预留data.length * 20个空间            StringBuilder sb = new StringBuilder((data.length << INT_RIGHT_SHIFT_SIZE) * 4);            int mask = ONE_MASK;            sb.append("low -> high \r\n");            for(int i=0; i<data.length; i++) {                int tmp = data[i];                for(int j=0; j<INT_SIZE; j++) {                    sb.append((tmp & mask) + " ");                    tmp >>>= 1;                }                sb.append("\r\n");            }            return sb.toString();        }    }}

效果截图

这里写图片描述

这里写图片描述

0 0