pub fn sort(src: &mut Vec<&str>) {
let hi = src.len() - 1;
sort_in_range(src, 0, hi, 0);
}
fn sort_in_range(src: &mut [&str], lo: usize, hi: usize, d: usize) {
if hi <= lo {
return;
}
let mut lt = lo;
let mut gt = hi;
let v = char_at(src[lo], d);
let mut i = lo + 1;
while i <= gt {
let t = char_at(src[i], d);
match t.partial_cmp(&v).unwrap() {
std::cmp::Ordering::Less => {
exch(src, lt, i);
lt += 1;
i += 1;
}
std::cmp::Ordering::Equal => i += 1,
std::cmp::Ordering::Greater => {
exch(src, i, gt);
gt -= 1;
}
}
}
if lo < lt {
sort_in_range(src, lo, lt - 1, d);
}
if v > 0 {
sort_in_range(src, lt, gt, d + 1);
}
sort_in_range(src, gt + 1, hi, d);
}
fn exch(src: &mut [&str], a: usize, b: usize) {
src.swap(a, b)
}
fn char_at(s: &str, d: usize) -> usize {
s.as_bytes().get(d).map_or(0, |f| *f as usize + 1)
}
#[cfg(test)]
mod test {
use super::sort;
#[test]
fn test() {
let mut src = vec![
"a",
"s",
"she",
"sells",
"seashells",
"by",
"the",
"sea",
"shore",
"the",
"shells",
"she",
"sells",
"are",
"surely",
"seashells",
];
sort(&mut src);
println!("{:?}", src);
}
}