1 //! Prefix similarity 2 use crate::{Algorithm, Result}; 3 4 /// Prefix similarity is the length of the longest common prefix for the given sequences. 5 /// 6 /// It's a very dumb metric but it can be surprisingly effective for comparing words 7 /// in languages with an extensive use of [suffixes](https://en.wikipedia.org/wiki/Suffix). 8 #[derive(Default)] 9 pub struct Prefix {} 10 11 impl Algorithm<usize> for Prefix { for_iter<C, E>(&self, mut s1: C, mut s2: C) -> Result<usize> where C: Iterator<Item = E>, E: Eq,12 fn for_iter<C, E>(&self, mut s1: C, mut s2: C) -> Result<usize> 13 where 14 C: Iterator<Item = E>, 15 E: Eq, 16 { 17 let mut result = 0; 18 let mut prev_match: bool = true; 19 let mut l1 = 0; 20 let mut l2 = 0; 21 loop { 22 match (s1.next(), s2.next()) { 23 (Some(c1), Some(c2)) => { 24 l1 += 1; 25 l2 += 1; 26 if c1 != c2 { 27 prev_match = false; 28 } else if prev_match { 29 result += 1; 30 } 31 } 32 (Some(_), None) => { 33 l1 += 1; 34 } 35 (None, Some(_)) => { 36 l2 += 1; 37 } 38 (None, None) => { 39 break; 40 } 41 } 42 } 43 Result { 44 abs: result, 45 is_distance: false, 46 max: l1.max(l2), 47 len1: l1, 48 len2: l2, 49 } 50 } 51 } 52 53 #[cfg(test)] 54 mod tests { 55 use crate::str::prefix; 56 use assert2::assert; 57 use rstest::rstest; 58 59 #[rstest] 60 #[case("", "", 0)] 61 #[case("", "a", 0)] 62 #[case("a", "", 0)] 63 #[case("a", "a", 1)] 64 #[case("a", "b", 0)] 65 #[case("abcde", "abcef", 3)] 66 #[case("abcde", "abcfde", 3)] 67 #[case("abcd", "bcd", 0)] function_str(#[case] s1: &str, #[case] s2: &str, #[case] exp: usize)68 fn function_str(#[case] s1: &str, #[case] s2: &str, #[case] exp: usize) { 69 assert!(prefix(s1, s2) == exp); 70 } 71 } 72