Skip to content

Commit b19c743

Browse files
Divakar-2508vil02
andauthored
Added move_to_front_encoding implementation (#874)
* Added move_to_front_encoding implementation * Update src/compression/move_to_front.rs Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com> * Removed unnescessary dbg!() and added macros for test_cases * replaced slices for Vec! --------- Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com>
1 parent b4aecf4 commit b19c743

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
* [Xor](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/xor.rs)
4747
* Compression
4848
* [Run Length Encoding](https://github.com/TheAlgorithms/Rust/blob/master/src/compression/run_length_encoding.rs)
49+
* [Move-To-Front Encoding](https://github.com/TheAlgorithms/Rust/blob/master/src/compression/move_to_front.rs)
4950
* Conversions
5051
* [Binary To Decimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/binary_to_decimal.rs)
5152
* [Binary To Hexadecimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/binary_to_hexadecimal.rs)

src/compression/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod move_to_front;
12
mod run_length_encoding;
23

4+
pub use self::move_to_front::{move_to_front_decode, move_to_front_encode};
35
pub use self::run_length_encoding::{run_length_decode, run_length_encode};

src/compression/move_to_front.rs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// https://en.wikipedia.org/wiki/Move-to-front_transform
2+
3+
fn blank_char_table() -> Vec<char> {
4+
(0..=255).map(|ch| ch as u8 as char).collect()
5+
}
6+
7+
pub fn move_to_front_encode(text: &str) -> Vec<u8> {
8+
let mut char_table = blank_char_table();
9+
let mut result = Vec::new();
10+
11+
for ch in text.chars() {
12+
if let Some(position) = char_table.iter().position(|&x| x == ch) {
13+
result.push(position as u8);
14+
char_table.remove(position);
15+
char_table.insert(0, ch);
16+
}
17+
}
18+
19+
result
20+
}
21+
22+
pub fn move_to_front_decode(encoded: &[u8]) -> String {
23+
let mut char_table = blank_char_table();
24+
let mut result = String::new();
25+
26+
for &pos in encoded {
27+
let ch = char_table[pos as usize];
28+
result.push(ch);
29+
char_table.remove(pos as usize);
30+
char_table.insert(0, ch);
31+
}
32+
33+
result
34+
}
35+
36+
#[cfg(test)]
37+
mod test {
38+
use super::*;
39+
40+
macro_rules! test_mtf {
41+
($($name:ident: ($text:expr, $encoded:expr),)*) => {
42+
$(
43+
#[test]
44+
fn $name() {
45+
assert_eq!(move_to_front_encode($text), $encoded);
46+
assert_eq!(move_to_front_decode($encoded), $text);
47+
}
48+
)*
49+
}
50+
}
51+
52+
test_mtf! {
53+
empty: ("", &[]),
54+
single_char: ("@", &[64]),
55+
repeated_chars: ("aaba", &[97, 0, 98, 1]),
56+
mixed_chars: ("aZ!", &[97, 91, 35]),
57+
word: ("banana", &[98, 98, 110, 1, 1, 1]),
58+
special_chars: ("\0\n\t", &[0, 10, 10]),
59+
}
60+
}

0 commit comments

Comments
 (0)