1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
pub mod bitset { const ONE_VALUE_LENGTH: usize = 63; const MAXIMUM: u64 = (1u64 << ONE_VALUE_LENGTH as u64) - 1; pub fn get_bit_position(index: usize) -> (usize, usize) { let data_index = index / ONE_VALUE_LENGTH; let bit_index = index % ONE_VALUE_LENGTH; (data_index, bit_index) } #[derive(PartialEq, Clone, Debug)] pub struct BitSet { data: Vec<u64>, } impl std::ops::BitOrAssign for BitSet { fn bitor_assign(&mut self, rhs: Self) { if self.data.len() < rhs.data.len() { self.data.resize(rhs.data.len(), 0); } let n = if self.data.len() > rhs.data.len() { rhs.data.len() } else { self.data.len() }; for i in 0..n { assert!(self.data[i] <= MAXIMUM); assert!(rhs.data[i] <= MAXIMUM); self.data[i] |= rhs.data[i]; } } } impl std::ops::Shl<usize> for BitSet { type Output = Self; fn shl(self, rhs: usize) -> Self { self.shift_left(rhs) } } impl BitSet { pub fn new(n: usize) -> Self { let size = (n + ONE_VALUE_LENGTH - 1) / ONE_VALUE_LENGTH; BitSet { data: vec![0; size], } } pub fn new_from(value: u64) -> Self { BitSet { data: vec![value] } } pub fn set(&mut self, index: usize, value: bool) { let (data_index, bit_index) = get_bit_position(index); assert!(self.data.len() > data_index); if value { self.data[data_index] |= (1 << bit_index) as u64; } else { let tmp = MAXIMUM ^ (1 << bit_index) as u64; self.data[data_index] &= tmp; } } pub fn get(&mut self, index: usize) -> bool { let (data_index, bit_index) = get_bit_position(index); assert!(self.data.len() > data_index); self.data[data_index] & (1u64 << bit_index as u64) != 0 } pub fn shift_left(&self, shift: usize) -> Self { let mut next_data = Vec::new(); let prefix_empty_count = shift / ONE_VALUE_LENGTH; let shift_count = (shift % ONE_VALUE_LENGTH) as u64; for _ in 0..prefix_empty_count { next_data.push(0); } let mut from_previous = 0; let room = ONE_VALUE_LENGTH as u64 - shift_count; for &data in self.data.iter() { let overflow = (data >> room) << room; let rest = data - overflow; let value = (rest << shift_count) + from_previous; assert!(value <= MAXIMUM); next_data.push(value); from_previous = overflow >> room; } if from_previous > 0 { next_data.push(from_previous); } BitSet { data: next_data } } } } #[cfg(test)] mod test { use super::bitset::*; #[test] fn test_set_bit() { let n = 10; let value = 717; let mut bitset = BitSet::new(n); for i in 0..n { if value & (1 << i) != 0 { bitset.set(i, true); } } for i in 0..n { if value & (1 << i) != 0 { assert!(bitset.get(i)); } else { assert!(!bitset.get(i)); } } } #[test] fn test_bitset_or() { let mut value1 = 717; let mut bitset1 = BitSet::new_from(value1); let value2 = 127; let bitset2 = BitSet::new_from(value2); value1 |= value2; bitset1 |= bitset2; for i in 0..50usize { if value1 & (1u64 << i as u64) != 0 { assert!(bitset1.get(i)); } else { assert!(!bitset1.get(i)); } } } #[test] fn test_bitset_shift_left() { let value1 = 717; let first_shift = 30; let second_shift = 40; let bitset1 = BitSet::new_from(value1) << (first_shift + second_shift); let bitset2 = BitSet::new_from(value1 << first_shift as u64) << second_shift; assert!(bitset1 == bitset2); } }