1 //! Suffix similarity 2 use crate::{Algorithm, Result}; 3 4 /// Suffix similarity is the length of the longest common suffix of the given sequences. 5 /// 6 /// It's a very dumb metric but it can work surprisingly well for comparing words 7 /// in languages with an active use of [prefixes](https://en.wikipedia.org/wiki/Prefix). 8 #[derive(Default)] 9 pub struct Suffix {} 10 11 impl Algorithm<usize> for Suffix { for_vec<E: Eq>(&self, s1: &[E], s2: &[E]) -> Result<usize>12 fn for_vec<E: Eq>(&self, s1: &[E], s2: &[E]) -> Result<usize> { 13 let mut result = 0; 14 for (c1, c2) in s1.iter().rev().zip(s2.iter().rev()) { 15 if c1 == c2 { 16 result += 1; 17 } else { 18 break; 19 } 20 } 21 let l1 = s1.len(); 22 let l2 = s2.len(); 23 Result { 24 abs: result, 25 is_distance: false, 26 max: l1.max(l2), 27 len1: l1, 28 len2: l2, 29 } 30 } 31 } 32 33 #[cfg(test)] 34 mod tests { 35 use crate::str::suffix; 36 use assert2::assert; 37 use rstest::rstest; 38 39 #[rstest] 40 #[case("", "", 0)] 41 #[case("", "a", 0)] 42 #[case("a", "", 0)] 43 #[case("a", "a", 1)] 44 #[case("a", "b", 0)] 45 #[case("abcde", "abcef", 0)] 46 #[case("abcde", "abfcde", 3)] 47 #[case("abcd", "fabcd", 4)] 48 function_str(#[case] s1: &str, #[case] s2: &str, #[case] exp: usize)49 fn function_str(#[case] s1: &str, #[case] s2: &str, #[case] exp: usize) { 50 assert!(suffix(s1, s2) == exp); 51 } 52 } 53