Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.14 KB | None | 0 0
  1. fn lcs<'a, T: Eq + 'a, I: ExactSizeIterator<Item = &'a T>>(
  2. x: impl ExactSizeIterator<Item = &'a T>,
  3. y: impl Fn() -> I
  4. ) -> Vec<usize> {
  5. let width = x.len() + 1;
  6. let mut c = vec![0; width * (y().len() + 1)];
  7.  
  8. for (i, x) in x.enumerate() {
  9. for (j, y) in y().enumerate() {
  10. c[(i + 1) * width + (j + 1)] = if x == y {
  11. c[i * width + j] + 1
  12. } else {
  13. c[(i + 1) * width + j].max(c[i * width + (j + 1)])
  14. };
  15. }
  16. }
  17.  
  18. c
  19. }
  20.  
  21. /*
  22. // Original Non-iter version
  23. fn lcs<T: Eq>(x: &[T], y: &[T]) -> Vec<usize> {
  24. let width = (x.len() + 1);
  25. let mut c = vec![0; width * (y.len() + 1)];
  26.  
  27. for i in 0..x.len() {
  28. for j in 0..y.len() {
  29. c[(i + 1) * width + (j + 1)] = if x[i] == y[j] {
  30. c[i * width + j] + 1
  31. } else {
  32. c[(i + 1) * width + j].max(c[i * width + (j + 1)])
  33. };
  34. }
  35. }
  36.  
  37. c
  38. }
  39. */
  40.  
  41. #[derive(Debug)]
  42. enum Edit<'a, T> {
  43. Copy(&'a T),
  44. Add(&'a T),
  45. Remove(&'a T),
  46. }
  47.  
  48. // TODO: Convert to iter version like above
  49. fn diff<'a, T: Eq>(
  50. c: &'a [usize], x: &'a [T], y: &'a [T], i: usize, j: usize, x_len: usize, y_len: usize
  51. ) -> Box<dyn Iterator<Item = Edit<'a, T>> + 'a> {
  52. if i > 0 && j > 0 && x[i - 1] == y[j - 1] {
  53. Box::new(diff(c, x, y, i - 1, j - 1, x_len, y_len)
  54. .chain(std::iter::once(Edit::Copy(&x[i - 1]))))
  55. } else if j > 0 && (i == 0 || c[i * (x_len + 1) + j - 1] >= c[(i - 1) * (x_len + 1) + j]) {
  56. Box::new(diff(c, x, y, i, j - 1, x_len, y_len)
  57. .chain(std::iter::once(Edit::Add(&y[j - 1]))))
  58. } else if i > 0 && (j == 0 || c[i * (x_len + 1) + j - 1] < c[(i - 1) * (x_len + 1) + j]) {
  59. Box::new(diff(c, x, y, i - 1, j, x_len, y_len)
  60. .chain(std::iter::once(Edit::Remove(&x[i - 1]))))
  61. } else {
  62. Box::new(std::iter::empty())
  63. }
  64. }
  65.  
  66. fn main() {
  67. // TODO: Non-raw
  68. let left = b"XMJYAUZ";
  69. let right = b"MZJAWXU";
  70.  
  71. let c = lcs(left.iter(), || right.iter());
  72.  
  73. println!("{:?}", diff(&c, left, right, left.len(), right.len(), left.len(), right.len())
  74. .collect::<Vec<_>>());
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement