#[derive(PartialEq, Debug, Clone)] enum DiffOp { Insert, Delete, Equal, } #[derive(Clone, Debug)] struct Diff { operation: DiffOp, data: String, } struct DiffMatchPatch { diff_timeout: f64, diff_edit_cost: isize, match_threshold: f64, match_distance: isize, patch_delete_threshold: f64, patch_margin: isize, } impl DiffMatchPatch { fn new() -> DiffMatchPatch { DiffMatchPatch { diff_timeout: 1.0, diff_edit_cost: 4, match_threshold: 0.5, match_distance: 1000, patch_delete_threshold: 0.5, patch_margin: 4, } } fn diff_main(&self, text1: &str, text2: &str) -> Vec { self.diff_compute(text1, text2) } fn diff_compute(&self, text1: &str, text2: &str) -> Vec { if text1.is_empty() { return vec![Diff { operation: DiffOp::Insert, data: text2.to_string(), }]; } if text2.is_empty() { return vec![Diff { operation: DiffOp::Delete, data: text1.to_string(), }]; } let mut diffs = Vec::new(); let mut i = 0; let mut j = 0; let text1_chars: Vec = text1.chars().collect(); let text2_chars: Vec = text2.chars().collect(); while i < text1_chars.len() && j < text2_chars.len() { if text1_chars[i] == text2_chars[j] { diffs.push(Diff { operation: DiffOp::Equal, data: text1_chars[i].to_string(), }); i += 1; j += 1; } else { // Simple case handling: deletion from text1 diffs.push(Diff { operation: DiffOp::Delete, data: text1_chars[i].to_string(), }); i += 1; // Simple case handling: insertion to text2 diffs.push(Diff { operation: DiffOp::Insert, data: text2_chars[j].to_string(), }); j += 1; } } // Handle any remaining characters in text1 while i < text1_chars.len() { diffs.push(Diff { operation: DiffOp::Delete, data: text1_chars[i].to_string(), }); i += 1; } // Handle any remaining characters in text2 while j < text2_chars.len() { diffs.push(Diff { operation: DiffOp::Insert, data: text2_chars[j].to_string(), }); j += 1; } diffs } } fn main() { let dmp = DiffMatchPatch::new(); let text1 = "能不能说一下你们现在的负债情况"; let text2 = "能哎能说按蓝你们现在的负债情况"; let diffs = dmp.diff_main(text1, text2); println!("Diffs: {:?}", diffs); }