LCS diff (WIP)
This commit is contained in:
parent
71210dfdac
commit
c124d6ccdb
|
@ -0,0 +1,74 @@
|
||||||
|
use std::cmp::max;
|
||||||
|
use std::str::Chars;
|
||||||
|
use crate::matrix::Matrix;
|
||||||
|
|
||||||
|
pub fn diff(a: &str, b: &str) {
|
||||||
|
let m = build_matrix(a, b);
|
||||||
|
print_diff(m, &mut a.chars(), &mut b.chars(), a.len() - 1, b.len() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_matrix(a: &str, b: &str) -> Matrix<i32> {
|
||||||
|
let mut a = a.chars();
|
||||||
|
let mut b = b.chars();
|
||||||
|
let mut m = Matrix::new(*(&a.count()), *(&b.count()), 0i32);
|
||||||
|
|
||||||
|
for i in 0..a.count() {
|
||||||
|
for j in 0..b.count() {
|
||||||
|
let x = a.nth(i).unwrap();
|
||||||
|
let y = b.nth(j).unwrap();
|
||||||
|
|
||||||
|
let v = if x == y {
|
||||||
|
if i == 0 || j == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
m.get(i - 1, j - 1).unwrap() + 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
max(
|
||||||
|
if j == 0 { 0 } else { *m.get(i, j - 1).unwrap() },
|
||||||
|
if i == 0 { 0 } else { *m.get(i - 1, j).unwrap() })
|
||||||
|
};
|
||||||
|
|
||||||
|
m.set(v, i, j).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_diff(m: Matrix<i32>, a: &mut Chars, b: &mut Chars, i: usize, j: usize) {
|
||||||
|
if i < 0 && j < 0 {
|
||||||
|
println!();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let char_i = a.nth(i).unwrap();
|
||||||
|
let char_j = b.nth(j).unwrap();
|
||||||
|
|
||||||
|
if i < 0 {
|
||||||
|
print_diff(m, a, b, i, j - 1);
|
||||||
|
println!("+ {char_i}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if j < 0 {
|
||||||
|
print_diff(m, a, b, i - 1, j);
|
||||||
|
println!("- {char_j}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if char_i == char_j {
|
||||||
|
print_diff(m, a, b, i - 1, j - 1);
|
||||||
|
println!(" {char_i}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.get(i, j - 1).unwrap() >= m.get(i - 1, j).unwrap() {
|
||||||
|
print_diff(m, a, b, i, j - 1);
|
||||||
|
println!("+ {char_j}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_diff(m, a, b, i - 1, j);
|
||||||
|
println!("- {char_i}");
|
||||||
|
}
|
50
src/main.rs
50
src/main.rs
|
@ -1,50 +1,12 @@
|
||||||
use std::cmp::min;
|
use crate::lcs::diff;
|
||||||
use std::io;
|
|
||||||
use crate::matrix::Matrix;
|
|
||||||
|
|
||||||
mod matrix;
|
mod matrix;
|
||||||
|
mod lcs;
|
||||||
|
|
||||||
const ADD_VAL: i32 = 1;
|
fn main() {
|
||||||
const MATCH_VAL: i32 = 0;
|
let a = "let a = \"ABCDE\";";
|
||||||
|
let b = "let b = \"ABCDE\";";
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
diff(a, b);
|
||||||
let str_a = "String A";
|
|
||||||
let str_b = "String B";
|
|
||||||
|
|
||||||
let mut diff_mat = Matrix::new(str_a.len(), str_b.len(), 0i32);
|
|
||||||
|
|
||||||
for col in 1..diff_mat.col_count {
|
|
||||||
let previous = diff_mat.get(0, col - 1).unwrap();
|
|
||||||
diff_mat.set(previous + ADD_VAL, 0, col).expect("Failed to initialize diff matrix");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for row in 1..diff_mat.row_count {
|
|
||||||
let previous = diff_mat.get(row - 1, 0).unwrap();
|
|
||||||
diff_mat.set(previous - ADD_VAL, row, 0).expect("Failed to initialize diff matrix");
|
|
||||||
}
|
|
||||||
|
|
||||||
for row in 1..diff_mat.row_count {
|
|
||||||
for col in 1..diff_mat.col_count {
|
|
||||||
let char_a = str_a.chars().nth(row).unwrap();
|
|
||||||
let char_b = str_b.chars().nth(col).unwrap();
|
|
||||||
|
|
||||||
let add_from = diff_mat.get(row, col - 1).unwrap();
|
|
||||||
let sub_from = diff_mat.get(row - 1, col).unwrap();
|
|
||||||
let substitute_from = diff_mat.get(row - 1, col - 1).unwrap();
|
|
||||||
|
|
||||||
let add = add_from + ADD_VAL;
|
|
||||||
let sub = sub_from - ADD_VAL;
|
|
||||||
let substitute = substitute_from + if char_a == char_b {
|
|
||||||
MATCH_VAL
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
|
|
||||||
let val = min(add, min(sub, substitute));
|
|
||||||
diff_mat.set(val, row, col).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff_mat.print();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue