数据转换算法(Burrows Wheeler Transform)

  1. pub fn burrows_wheeler_transform(input: String) -> (String, usize) {
  2. let len = input.len();
  3. let mut table = Vec::<String>::with_capacity(len);
  4. for i in 0..len {
  5. table.push(input[i..].to_owned() + &input[..i]);
  6. }
  7. table.sort_by_key(|a| a.to_lowercase());
  8. let mut encoded = String::new();
  9. let mut index: usize = 0;
  10. for (i, item) in table.iter().enumerate().take(len) {
  11. encoded.push(item.chars().last().unwrap());
  12. if item.eq(&input) {
  13. index = i;
  14. }
  15. }
  16. (encoded, index)
  17. }
  18. pub fn inv_burrows_wheeler_transform(input: (String, usize)) -> String {
  19. let len = input.0.len();
  20. let mut table = Vec::<(usize, char)>::with_capacity(len);
  21. for i in 0..len {
  22. table.push((i, input.0.chars().nth(i).unwrap()));
  23. }
  24. table.sort_by(|a, b| a.1.cmp(&b.1));
  25. let mut decoded = String::new();
  26. let mut idx = input.1;
  27. for _ in 0..len {
  28. decoded.push(table[idx].1);
  29. idx = table[idx].0;
  30. }
  31. decoded
  32. }
  33. #[cfg(test)]
  34. mod tests {
  35. use super::*;
  36. #[test]
  37. fn basic() {
  38. assert_eq!(
  39. inv_burrows_wheeler_transform(burrows_wheeler_transform("CARROT".to_string())),
  40. "CARROT"
  41. );
  42. assert_eq!(
  43. inv_burrows_wheeler_transform(burrows_wheeler_transform("TOMATO".to_string())),
  44. "TOMATO"
  45. );
  46. assert_eq!(
  47. inv_burrows_wheeler_transform(burrows_wheeler_transform("THISISATEST".to_string())),
  48. "THISISATEST"
  49. );
  50. assert_eq!(
  51. inv_burrows_wheeler_transform(burrows_wheeler_transform("THEALGORITHMS".to_string())),
  52. "THEALGORITHMS"
  53. );
  54. assert_eq!(
  55. inv_burrows_wheeler_transform(burrows_wheeler_transform("RUST".to_string())),
  56. "RUST"
  57. );
  58. }
  59. #[test]
  60. fn special_characters() {
  61. assert_eq!(
  62. inv_burrows_wheeler_transform(burrows_wheeler_transform("!.!.!??.=::".to_string())),
  63. "!.!.!??.=::"
  64. );
  65. assert_eq!(
  66. inv_burrows_wheeler_transform(burrows_wheeler_transform(
  67. "!{}{}(((&&%%!??.=::".to_string()
  68. )),
  69. "!{}{}(((&&%%!??.=::"
  70. );
  71. assert_eq!(
  72. inv_burrows_wheeler_transform(burrows_wheeler_transform("//&$[]".to_string())),
  73. "//&$[]"
  74. );
  75. }
  76. #[test]
  77. fn empty() {
  78. assert_eq!(
  79. inv_burrows_wheeler_transform(burrows_wheeler_transform("".to_string())),
  80. ""
  81. );
  82. }
  83. }