[lab2] Uncompressed bit vector to allow elements referencing
This commit is contained in:
parent
cda30bd374
commit
50e2fa9a64
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,4 +2,5 @@ mod bit_vector;
|
|||||||
mod operations;
|
mod operations;
|
||||||
mod r#impl;
|
mod r#impl;
|
||||||
|
|
||||||
pub use bit_vector::BitVector;
|
pub use bit_vector::BitVector;
|
||||||
|
pub use r#impl::adaptiveResonanceTheoryImpl;
|
||||||
Loading…
Reference in New Issue
Block a user