difference/
lcs.rs
1use std::cmp::max;
2
3fn strsplit<'a>(s: &'a str, split: &str) -> Vec<&'a str> {
7 let mut si = s.split(split);
8 if split == "" {
9 si.next();
10 }
11 let mut v: Vec<&str> = si.collect();
12 if split == "" {
13 v.pop();
14 }
15 v
16}
17
18#[allow(non_snake_case)]
25#[cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
26pub fn lcs(orig: &str, edit: &str, split: &str) -> (i32, String) {
27 let a = strsplit(orig, split);
29 let b = strsplit(edit, split);
30
31 let N = a.len();
32 let M = b.len();
33
34 let mut idx: Vec<usize> = Vec::with_capacity(N * M);
35 idx.resize(N * M, 0);
36
37 for i in 0..N {
38 for j in 0..M {
39 if b[j] == a[i] {
40 if i == 0 || j == 0 {
41 idx[i * M + j] = 1;
42 } else {
43 idx[i * M + j] = idx[(i - 1) * M + j - 1] + 1;
44 }
45 } else if i == 0 {
46 if j == 0 {
47 idx[i * M + j] = 0;
48 } else {
49 idx[i * M + j] = idx[i * M + j - 1];
50 }
51 } else if j == 0 {
52 idx[i * M + j] = idx[(i - 1) * M + j];
53 } else {
54 idx[i * M + j] = max(idx[i * M + j - 1], idx[(i - 1) * M + j]);
55 }
56 }
57 }
58
59 let mut i = (N as isize) - 1;
60 let mut j = (M as isize) - 1;
61 let mut lcs = Vec::new();
62 while i >= 0 && j >= 0 {
63 let ui = i as usize;
64 let uj = j as usize;
65 if a[ui] == b[uj] {
66 lcs.push(a[ui]);
67 i -= 1;
68 j -= 1;
69 } else if j == 0 && i == 0 {
70 break;
71 } else if i == 0 || idx[ui * M + uj - 1] > idx[(ui - 1) * M + uj] {
72 j -= 1;
73 } else {
74 i -= 1;
75 }
76 }
77
78 lcs.reverse();
79 ((N + M - 2 * lcs.len()) as i32, lcs.join(split))
80}
81
82#[test]
83fn test_lcs() {
84 assert_eq!(lcs("test", "tost", ""), (2, "tst".to_string()));
85 assert_eq!(lcs("test", "test", ""), (0, "test".to_string()));
86
87 assert_eq!(lcs("test", "test", " "), (0, "test".to_string()));
88
89 assert_eq!(
90 lcs(
91 "The quick brown fox jumps over the lazy dog",
92 "The quick brown dog leaps over the lazy cat",
93 "",
94 ),
95 (16, "The quick brown o ps over the lazy ".to_string())
96 );
97 assert_eq!(
98 lcs(
99 "The quick brown fox jumps over the lazy dog",
100 "The quick brown dog leaps over the lazy cat",
101 " ",
102 ),
103 (6, "The quick brown over the lazy".to_string())
104 );
105
106 assert_eq!(
107 lcs(
108 "The quick brown fox jumps over the lazy dog",
109 "The quick brown dog leaps over the lazy cat",
110 "\n",
111 ),
112 (2, "".to_string())
113 );
114 assert_eq!(
115 lcs(
116 "The quick brown fox jumps over the lazy dog",
117 "The quick brown fox jumps over the lazy dog",
118 "\n",
119 ),
120 (0, "The quick brown fox jumps over the lazy dog".to_string())
121 );
122
123 assert_eq!(
124 lcs("a b : c", "b a : b : c", " "),
125 (2, "a b : c".to_string())
126 );
127
128 assert_eq!(lcs("", "a b c", ""), (5, "".to_string()));
129
130 assert_eq!(lcs("", " a", " "), (1, "".to_string()));
131}