『アルゴリズムとデータ構造』を Rust で実装してみるシリーズ。5章の動的計画法。
前回 → https://quantized-cube.com/rust-dp-03
今回は編集距離。
use proconio::input;
fn input(use_default_values: bool) -> (String, String) {
if use_default_values {
let s = String::from("logistic");
let t = String::from("algorithm");
return (s, t);
} else {
println!("Input s and t:");
input! {
s: String,
t: String,
}
return (s, t);
}
}
const INF: i64 = 1 << 29; // 十分大きな値 (ここでは 2^29 とする)
fn chmin<T: PartialOrd>(a: &mut T, b: T) {
if *a > b {
*a = b;
}
}
/// 編集距離を動的計画法を用いて求める
pub fn code_5_8(use_default_values: bool) -> i64 {
// 入力
let (s, t) = input(use_default_values);
// DP テーブル定義
let mut dp = vec![vec![INF; t.len() + 1]; s.len() + 1];
// DP 初期条件
dp[0][0] = 0;
// DPループ
for i in 0..s.len() + 1 {
for j in 0..t.len() + 1 {
// 変更操作
if i > 0 && j > 0 {
let b = dp[i - 1][j - 1];
if s.as_bytes()[i - 1] == t.as_bytes()[j - 1] {
chmin(&mut dp[i][j], b);
} else {
chmin(&mut dp[i][j], b + 1);
}
}
// 削除操作
if i > 0 {
let b = dp[i - 1][j] + 1;
chmin(&mut dp[i][j], b);
};
// 挿入操作
if j > 0 {
let b = dp[i][j - 1] + 1;
chmin(&mut dp[i][j], b);
};
}
}
// 答えの出力
dp[s.len()][t.len()]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn code_5_8_works() {
let result = code_5_8(true);
assert_eq!(result, 6);
}
}
GitHub のリポジトリはこちら https://github.com/quantized-cube/book_algorithm_solution_rust
コメント