lev_dist源码
(没想到在这种时候,编译器还在守护我(╥﹏╥),rustc,你真的)
用于 typo 检查和拼写错误时的候选词的建议。
在 Rust 源码文件夹的 compiler/rustc_span/src/lev_distance.rs。
edit_distance 算法的应用演示:
lvy rust$ rustup dog
: The subcommand 'dog' wasn't recognized
Did you mean 'doc'?
如上所示,输入 rustup dog 时,rustup 不存在 dog 这个子命令,但是它会挨个遍历候选词中最接近的一个词。
最后建议把 dog 改成 doc ,因为 dog 和 doc 之间 edit_distance 最小。
工程项目中可以用 strsim 库提供的 edit_distance 算法,例如过程宏库 darling 和 async-graphql 都用到了 strsim 库
/// https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/lev_distance.rs
fn lev_distance(a: &str, b: &str) -> usize {
// cases which don't require further computation
if a.is_empty() {
return b.chars().count();
} else if b.is_empty() {
return a.chars().count();
}
let mut dcol: Vec<_> = (0..=b.len()).collect();
let mut t_last = 0;
for (i, sc) in a.chars().enumerate() {
let mut current = i;
dcol0 = current + 1;
for (j, tc) in b.chars().enumerate() {
let next = dcolj + 1;
if sc == tc {
dcolj + 1 = current;
} else {
dcolj + 1 = std::cmp::min(current, next);
dcolj + 1 = std::cmp::min(dcolj + 1, dcolj) + 1;
}
current = next;
t_last = j;
}
}
dcolt_last + 1
}
lc66
impl Solution {
pub fn plus_one(mut digits: Vec<i32>) -> Vec<i32> {
for d in digits.iter_mut().rev() {
if *d < 9 {
*d += 1; // 进位
return digits;
}
*d = 0; // 进位数字的右边数字都变成 0
}
// digits 全是 9,加一后变成 100...00
digits.push(0);
digits0 = 1;
digits
}
}
lc53
3步,前缀和+贪心
impl Solution {
pub fn max_sub_array(nums: Vec<i32>) -> i32 {
let mut ans = i32::MIN;
let mut min_pre_sum = 0;
let mut pre_sum = 0;
for x in nums {
pre_sum += x; // 当前的前缀和
ans = ans.max(pre_sum - min_pre_sum); // 减去前缀和的最小值
min_pre_sum = min_pre_sum.min(pre_sum); // 维护前缀和的最小值
}
ans
}
}
lc46
利用swap,swap真是个数组的原子操作!熟练掌握swap的使用几乎能完全所有数组的原地变换🥺
pub fn per(v: &mut Vec<i32>, idx: usize, res: &mut Vec<Vec<i32>>) {
if idx == v.len() {
res.push(v.clone());
return;
}
for i in idx..v.len() {
unsafe { std::ptr::swap(&mut vidx, &mut vi); }
per(v, idx + 1, res);
unsafe { std::ptr::swap(&mut vi, &mut vidx); }
}
}
impl Solution {
pub fn permute(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
let len = (2..=nums.len()).product();
let mut res = Vec::with_capacity(len);
per(&mut nums, 0, &mut res);
res
}
}