use crate::insert_sort;
const M: usize = 0;
const R: usize = 256;
pub fn sort(src: &mut Vec<&str>) {
let n = src.len();
let mut aux = vec![""; n];
sort_in_range(src, &mut aux, 0, n - 1, 0);
}
fn sort_in_range<'a>(src: &mut [&'a str], aux: &mut [&'a str], lo: usize, hi: usize, d: usize) {
if hi <= lo {
return;
}
if hi <= lo + M {
insert_sort(src);
return;
}
let mut count = [0; R + 2];
for i in lo..=hi {
count[char_at(src[i], d) + 1] += 1;
}
for r in 0..R + 1 {
count[r + 1] += count[r];
}
(lo..=hi).for_each(|i| {
let pos = char_at(src[i], d);
aux[count[pos]] = src[i];
count[pos] += 1;
});
(lo..=hi).for_each(|i| {
src[i] = aux[i - lo];
});
let d = d + 1;
for i in 0..R {
if count[i] < count[i + 1] {
sort_in_range(src, aux, lo + count[i], lo + count[i + 1] - 1, d);
}
}
}
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![
"she",
"a",
"",
"sells",
"seashells",
"by",
"the",
"sea",
"shore",
"the",
"shells",
"shea",
"sells",
"are",
"surely",
"seashells",
];
sort(&mut src);
println!("{:?}", src);
}
}