Skip to content

Instantly share code, notes, and snippets.

@ttappr
Created December 31, 2023 00:40
Show Gist options
  • Save ttappr/921909f7739f2ce66ef1ddd4a3ed5f19 to your computer and use it in GitHub Desktop.
Save ttappr/921909f7739f2ce66ef1ddd4a3ed5f19 to your computer and use it in GitHub Desktop.
A radix sort for vectors of strings with only ASCII compatible characters.
use std::mem::swap;
const ASCII_START: usize = b' ' as usize;
const ASCII_END : usize = b'~' as usize;
fn ascii_count_sort(arr: &mut Vec<String>, place: usize) {
let size = arr.len();
let mut output = vec![String::default(); size];
let mut count = [0; ASCII_END - ASCII_START + 1];
for string in arr.iter() {
debug_assert!(string.is_ascii(),
"All string characters must be within ascii range.");
let index = *string.as_bytes()
.get(place)
.unwrap_or(&b' ') as usize - ASCII_START;
count[index] += 1;
}
for i in 1..count.len() {
count[i] += count[i - 1];
}
for i in (0..size).rev() {
let index = *arr[i].as_bytes()
.get(place)
.unwrap_or(&b' ') as usize - ASCII_START;
swap(&mut output[count[index] - 1], &mut arr[i]);
count[index] -= 1;
}
swap(arr, &mut output);
}
pub fn ascii_radix_sort(arr: &mut Vec<String>) {
if let Some(max_len) = arr.iter().map(|s| s.len()).max() {
for i in (0..max_len).rev() {
ascii_count_sort(arr, i);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ascii_radix_sort() {
let a = ["algorithm", "radix", "sort", "test", "unsorted", "words",
"list", "give", "can", "you", "me", "thirty", "random", "for",
"to", "your", "use", "data", "structures", "computer",
"science", "programming", "python", "java", "ruby",
"javascript", "swift", "kotlin", "rust", "go"];
let b = ["algorithm", "can", "computer", "data", "for", "give", "go",
"java", "javascript", "kotlin", "list", "me", "programming",
"python", "radix", "random", "ruby", "rust", "science", "sort",
"structures", "swift", "test", "thirty", "to", "unsorted",
"use", "words", "you", "your"];
let mut arr = a.iter().map(|s| s.to_string()).collect::<Vec<_>>();
let exp = b.iter().map(|s| s.to_string()).collect::<Vec<_>>();
ascii_radix_sort(&mut arr);
assert_eq!(arr, exp);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment