[lab2] Uncompressed bit vector to allow elements referencing

This commit is contained in:
Andrew Golovashevich 2026-01-29 23:16:52 +03:00
parent cda30bd374
commit 50e2fa9a64
2 changed files with 20 additions and 36 deletions

View File

@ -2,15 +2,13 @@ use std::cmp::min;
use std::ops::{BitAnd, BitAndAssign, Index, IndexMut, Not, Shl}; use std::ops::{BitAnd, BitAndAssign, Index, IndexMut, Not, Shl};
pub struct BitVector { pub struct BitVector {
len: usize, data: Box<[bool]>,
data: Box<[usize]>,
} }
impl BitVector { impl BitVector {
pub fn alloc(len: usize) -> Self { pub fn alloc(len: usize) -> Self {
return Self { return Self {
len, data: vec![false; len]
data: vec![0usize; (len + (usize::BITS as usize) - 1) / (usize::BITS as usize)]
.into_boxed_slice(), .into_boxed_slice(),
}; };
} }
@ -18,25 +16,22 @@ impl BitVector {
pub fn count1(&self) -> usize { pub fn count1(&self) -> usize {
let mut counter = 0usize; let mut counter = 0usize;
for i in 0..(self.data.len() - 1) { for i in 0..(self.data.len() - 1) {
counter += self.data[i].count_ones() as usize; if self.data[i] {
counter += 1;
}
} }
counter += (self.data[self.data.len() - 1]
& (0usize.not().shl(self.len % (usize::BITS as usize)).not()))
.count_ones() as usize;
return counter; return counter;
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
return self.len; return self.data.len();
} }
} }
impl Clone for BitVector { impl Clone for BitVector {
fn clone(&self) -> Self { fn clone(&self) -> Self {
return Self { return Self {
len: self.len,
data: self.data.clone(), data: self.data.clone(),
}; };
} }
@ -54,39 +49,27 @@ impl BitAnd<Self> for &BitVector {
impl BitAndAssign<&Self> for BitVector { impl BitAndAssign<&Self> for BitVector {
fn bitand_assign(&mut self, rhs: &Self) { fn bitand_assign(&mut self, rhs: &Self) {
assert_eq!(self.len, rhs.len, "Vectors has different length's"); assert_eq!(self.data.len(), rhs.data.len(), "Vectors has different length's");
for i in 0..self.data.len() { for i in 0..self.data.len() {
self.data[i] &= rhs.data[i] self.data[i] &= rhs.data[i]
} }
} }
} }
struct _BitLocation { impl Index<usize> for BitVector {
offset: usize, type Output = bool;
mask: usize,
fn index(&self, index: usize) -> &Self::Output {
assert!(index < self.data.len());
return &self.data[index]
}
} }
impl BitVector {
fn _unpackIndex(&self, i: usize) -> _BitLocation {
assert!(i < self.len);
return _BitLocation {
offset: i / (usize::BITS as usize),
mask: 1 << i % (usize::BITS as usize),
};
}
pub fn get(&self, i: usize) -> bool { impl IndexMut<usize> for BitVector {
let bl = self._unpackIndex(i); fn index_mut(&mut self, index: usize) -> &mut Self::Output {
return self.data[bl.offset] & bl.mask != 0; assert!(index < self.data.len());
} return &mut self.data[index]
pub fn set(&mut self, i: usize, value: bool) {
let bl = self._unpackIndex(i);
if value {
self.data[bl.offset] |= bl.mask;
} else {
self.data[bl.offset] &= !bl.mask;
}
} }
} }

View File

@ -3,3 +3,4 @@ mod operations;
mod r#impl; mod r#impl;
pub use bit_vector::BitVector; pub use bit_vector::BitVector;
pub use r#impl::adaptiveResonanceTheoryImpl;