• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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