lcs.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use crate::{patch::OpMethod, util::str_to_chars};
  2. pub struct Lcs<'a> {
  3. a: Vec<&'a str>,
  4. b: Vec<&'a str>,
  5. lengths: Vec<Vec<u64>>,
  6. }
  7. impl<'a> Lcs<'a> {
  8. pub fn new(a: &'a str, b: &'a str) -> Self {
  9. let a: Vec<_> = str_to_chars(a);
  10. let b: Vec<_> = str_to_chars(b);
  11. let (na, nb) = (a.len(), b.len());
  12. let mut lengths = vec![vec![0; nb + 1]; na + 1];
  13. for (i, ci) in a.iter().enumerate() {
  14. for (j, cj) in b.iter().enumerate() {
  15. lengths[i + 1][j + 1] = if ci == cj {
  16. lengths[i][j] + 1
  17. } else {
  18. lengths[i][j + 1].max(lengths[i + 1][j])
  19. }
  20. }
  21. }
  22. Self { a, b, lengths }
  23. }
  24. fn op(&self, ops: &mut Vec<OpMethod>, i: usize, j: usize) {
  25. if i == 0 && j == 0 {
  26. return
  27. }
  28. if i == 0 {
  29. ops.push(OpMethod::Insert(self.b[j - 1].to_string()));
  30. self.op(ops, i, j - 1);
  31. } else if j == 0 {
  32. ops.push(OpMethod::Delete((1) as _));
  33. self.op(ops, i - 1, j);
  34. } else if self.a[i - 1] == self.b[j - 1] {
  35. ops.push(OpMethod::Retain((1) as _));
  36. self.op(ops, i - 1, j - 1);
  37. } else if self.lengths[i - 1][j] > self.lengths[i][j - 1] {
  38. ops.push(OpMethod::Delete((1) as _));
  39. self.op(ops, i - 1, j);
  40. } else {
  41. ops.push(OpMethod::Insert(self.b[j - 1].to_string()));
  42. self.op(ops, i, j - 1);
  43. }
  44. }
  45. pub fn ops(&self) -> Vec<OpMethod> {
  46. let mut ops = vec![];
  47. self.op(&mut ops, self.a.len(), self.b.len());
  48. ops.reverse();
  49. ops
  50. }
  51. }
  52. #[cfg(test)]
  53. mod tests {
  54. use super::*;
  55. #[test]
  56. fn test_lcs() {
  57. let lcs = Lcs::new("hello", "test hello");
  58. assert_eq!(
  59. lcs.ops(),
  60. vec![
  61. OpMethod::Insert("t".into()),
  62. OpMethod::Insert("e".into()),
  63. OpMethod::Insert("s".into()),
  64. OpMethod::Insert("t".into()),
  65. OpMethod::Insert(" ".into()),
  66. OpMethod::Retain(1),
  67. OpMethod::Retain(1),
  68. OpMethod::Retain(1),
  69. OpMethod::Retain(1),
  70. OpMethod::Retain(1),
  71. ]
  72. );
  73. let lcs = Lcs::new("hello world", "hello");
  74. assert_eq!(
  75. lcs.ops(),
  76. vec![
  77. OpMethod::Retain(1),
  78. OpMethod::Retain(1),
  79. OpMethod::Retain(1),
  80. OpMethod::Retain(1),
  81. OpMethod::Delete(1),
  82. OpMethod::Delete(1),
  83. OpMethod::Delete(1),
  84. OpMethod::Retain(1),
  85. OpMethod::Delete(1),
  86. OpMethod::Delete(1),
  87. OpMethod::Delete(1),
  88. ]
  89. );
  90. }
  91. }