From d5065151f14f7109052b9fde1159227966aa257b Mon Sep 17 00:00:00 2001 From: Antonio De Lucreziis Date: Wed, 30 Oct 2024 00:42:26 +0100 Subject: [PATCH] chore: cleaned up rolling hash --- src/main.rs | 4 +-- src/rolling_hash/mod.rs | 76 +++++++---------------------------------- 2 files changed, 15 insertions(+), 65 deletions(-) diff --git a/src/main.rs b/src/main.rs index a18895b..b3f4a80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use gfa::{Entry, Orientation}; use graph::{AdjacencyGraph, DirectedAcyclicGraph, Graph}; use indicatif::ProgressIterator; use rand::seq::SliceRandom; -use rolling_hash::RollingHash; +use rolling_hash::RollingHasher; #[derive(FromArgs, PartialEq, Debug)] /// Strumento CLI per il progetto di Algoritmi e Strutture Dati 2024 @@ -264,7 +264,7 @@ fn compute_sequence_occurrences_rolling_hash(sequence: &str, pattern: &str) -> V let mut occurrences = vec![]; - let mut rl = RollingHash::new(3000, 5); + let mut rl = RollingHasher::new(3000, 5); // let mut rl = RollingHash::new(1_000_000, 5); let pattern_hash = rl.hash_pattern(&pattern.chars().map(letter_to_number).collect::>()); diff --git a/src/rolling_hash/mod.rs b/src/rolling_hash/mod.rs index cc38c5f..0d1f3d7 100644 --- a/src/rolling_hash/mod.rs +++ b/src/rolling_hash/mod.rs @@ -1,6 +1,6 @@ use std::{collections::VecDeque, fmt::Debug}; -pub struct RollingHash + Clone> { +pub struct RollingHasher + Clone> { modulus: u64, alphabet_size: u64, @@ -15,27 +15,12 @@ pub struct Hashed { offset: u64, } -fn wrapping_pow_correct(a: u64, b: u64) -> u64 { - // // println!("Wrapping pow: {}^{}", a, b); - - // let mut result = 1u64; - // for _ in 0..b { - // result = result.wrapping_mul(a); - // } - - // // println!("=> {}", result); - - // result - - a.wrapping_pow(b as u32) -} - -impl RollingHash +impl RollingHasher where T: Into + Clone + Debug, { pub fn new(modulus: u64, alphabet_size: u64) -> Self { - RollingHash { + RollingHasher { modulus, alphabet_size, @@ -45,10 +30,6 @@ where } } - // pub fn hash(&self) -> u64 { - // self.hash % self.modulus - // } - pub fn hash(&self) -> Hashed { Hashed { hash: self.hash % self.modulus, @@ -57,8 +38,6 @@ where } pub fn compare(&self, lhs: &Hashed, rhs: &Hashed) -> bool { - // println!("Comparing: {:?} {:?}", lhs, rhs); - let (lhs, rhs) = if lhs.offset < rhs.offset { (lhs, rhs) } else { @@ -66,10 +45,10 @@ where }; // Shift lhs to the right by the difference in offsets - let shifted_lhs = (lhs.hash.wrapping_mul(wrapping_pow_correct( - self.alphabet_size, - rhs.offset - lhs.offset, - ))) % self.modulus; + let shifted_lhs = (lhs.hash.wrapping_mul( + self.alphabet_size + .wrapping_pow((rhs.offset - lhs.offset) as u32), + )) % self.modulus; shifted_lhs == rhs.hash } @@ -78,8 +57,7 @@ where let mut hash = 0; for (i, value) in pattern.iter().enumerate() { - let char_hash = - value.clone().into() * wrapping_pow_correct(self.alphabet_size, i as u64); + let char_hash = value.clone().into() * self.alphabet_size.wrapping_pow(i as u32); hash += char_hash; } @@ -91,20 +69,10 @@ where self.current_word.push_back(value.clone()); let i = self.offset + (self.current_word.len() as u64) - 1; - - // println!("Alphabet size: {}", self.alphabet_size); - // println!("Index: {}", i); - - // println!( - // "Adding: {:?} * {} to {}", - // value, - // wrapping_pow_correct(self.alphabet_size, i), - // self.hash - // ); self.hash = self.hash.wrapping_add( value .into() - .wrapping_mul(wrapping_pow_correct(self.alphabet_size, i)), + .wrapping_mul(self.alphabet_size.wrapping_pow(i as u32)), ); } @@ -116,7 +84,7 @@ where self.hash = self.hash.wrapping_sub( value .into() - .wrapping_mul(wrapping_pow_correct(self.alphabet_size, i)), + .wrapping_mul(self.alphabet_size.wrapping_pow(i as u32)), ); self.offset += 1; @@ -137,7 +105,7 @@ where panic!("Invalid position"); } - (hash * wrapping_pow_correct(self.alphabet_size, diff as u64)) % self.modulus + (hash * self.alphabet_size.wrapping_pow(diff as u32)) % self.modulus } pub fn hash_value_at_caret(&self, h: &Hashed) -> u64 { @@ -156,7 +124,7 @@ mod tests { let modulus = 42; let alphabet_size = 4; - let mut rh = RollingHash::::new(modulus, alphabet_size); + let mut rh = RollingHasher::::new(modulus, alphabet_size); let initial_pattern_hash = rh.hash_pattern(&[1, 2, 3, 4, 5]); println!("Initial pattern hash: {:?}", initial_pattern_hash); @@ -206,7 +174,7 @@ mod tests { let modulus = 10_000_000; let alphabet_size = 2; - let mut rh = RollingHash::::new(modulus, alphabet_size); + let mut rh = RollingHasher::::new(modulus, alphabet_size); let initial_pattern_hash = rh.hash_pattern(&[1, 1, 1, 1]); @@ -226,22 +194,4 @@ mod tests { rh.hash_value_at(&initial_pattern_hash, rh.offset) ); } - - #[test] - fn test_wrappping_pow() { - println!("Wrapping pow test"); - - let a = 2; - let b = 3; - - let result = wrapping_pow_correct(a, b); - - assert_eq!(result, 8); - - let a = 3; - let b = 100; - let result = wrapping_pow_correct(a, b); - - assert_ne!(result, 0); - } }