Skip to content

Commit 5fec0a9

Browse files
authored
Add run length encoding (TheAlgorithms#369)
1 parent 433163d commit 5fec0a9

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ These are for demonstration purposes only.
114114
- [x] [Manacher](./src/string/manacher.rs)
115115
- [x] [Rabin Carp](./src/string/rabin_karp.rs)
116116
- [x] [Reverse](./src/string/reverse.rs)
117+
- [x] [Run Length Encoding](.src/string/run_length_encoding.rs)
117118
- [x] [Hamming Distance](./src/string/hamming_distance.rs)
118119

119120
## [General](./src/general)

src/string/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,9 @@ to find an exact match of a pattern string in a text.
4747
### [Hamming Distance](./hamming_distance.rs)
4848
From [Wikipedia][hamming-distance-wiki]: In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other. In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences. It is named after the American mathematician Richard Hamming.
4949

50+
[run-length-encoding-wiki]: https://en.wikipedia.org/wiki/Run-length_encoding
51+
52+
### [Run Length Encoding](./run_lentgh_encoding.rs)
53+
From [Wikipedia][run-length-encoding-wiki]: a form of lossless data compression in which runs of data (sequences in which the same data value occurs in many consecutive data elements) are stored as a single data value and count, rather than as the original run.
54+
5055
[hamming-distance-wiki]: https://en.wikipedia.org/wiki/Hamming_distance

src/string/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod knuth_morris_pratt;
55
mod manacher;
66
mod rabin_karp;
77
mod reverse;
8+
mod run_length_encoding;
89
mod z_algorithm;
910

1011
pub use self::aho_corasick::AhoCorasick;
@@ -16,5 +17,6 @@ pub use self::knuth_morris_pratt::knuth_morris_pratt;
1617
pub use self::manacher::manacher;
1718
pub use self::rabin_karp::rabin_karp;
1819
pub use self::reverse::reverse;
20+
pub use self::run_length_encoding::{run_length_decoding, run_length_encoding};
1921
pub use self::z_algorithm::match_pattern;
2022
pub use self::z_algorithm::z_array;

src/string/run_length_encoding.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
pub fn run_length_encoding(target: String) -> String {
2+
if target.trim().is_empty() {
3+
return "String is Empty!".to_string();
4+
}
5+
let mut count: i32 = 0;
6+
let mut base_character: String = "".to_string();
7+
let mut encoded_target = String::new();
8+
9+
for c in target.as_str().chars() {
10+
if base_character == *"" {
11+
base_character = c.to_string();
12+
}
13+
if c.to_string() == base_character {
14+
count += 1;
15+
} else {
16+
encoded_target.push_str(&count.to_string());
17+
count = 1;
18+
encoded_target.push_str(&base_character);
19+
base_character = c.to_string();
20+
}
21+
}
22+
encoded_target.push_str(&count.to_string());
23+
encoded_target.push_str(&base_character);
24+
25+
encoded_target
26+
}
27+
28+
pub fn run_length_decoding(target: String) -> String {
29+
if target.trim().is_empty() {
30+
return "String is Empty!".to_string();
31+
}
32+
33+
let mut character_count: String = String::new();
34+
let mut encoded_target = String::new();
35+
36+
for c in target.as_str().chars() {
37+
character_count.push(c);
38+
let is_numeric: bool = character_count.parse::<i32>().is_ok();
39+
40+
if !is_numeric {
41+
let pop_char: char = character_count.pop().unwrap();
42+
encoded_target.push_str(
43+
&pop_char
44+
.to_string()
45+
.repeat(character_count.parse().unwrap()),
46+
);
47+
character_count = "".to_string();
48+
}
49+
}
50+
51+
encoded_target
52+
}
53+
54+
#[cfg(test)]
55+
mod tests {
56+
use super::*;
57+
58+
#[test]
59+
fn encode_empty() {
60+
assert_eq!(
61+
(run_length_encoding("".to_string())),
62+
"String is Empty!".to_string()
63+
)
64+
}
65+
66+
#[test]
67+
fn encode_identical_character() {
68+
assert_eq!(
69+
(run_length_encoding("aaaaaaaaaa".to_string())),
70+
"10a".to_string()
71+
)
72+
}
73+
#[test]
74+
fn encode_continuous_character() {
75+
assert_eq!(
76+
(run_length_encoding("abcdefghijk".to_string())),
77+
"1a1b1c1d1e1f1g1h1i1j1k".to_string()
78+
)
79+
}
80+
81+
#[test]
82+
fn encode_random_character() {
83+
assert_eq!(
84+
(run_length_encoding("aaaaabbbcccccdddddddddd".to_string())),
85+
"5a3b5c10d".to_string()
86+
)
87+
}
88+
89+
#[test]
90+
fn encode_long_character() {
91+
assert_eq!(
92+
(run_length_encoding(
93+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbcccccdddddddddd".to_string()
94+
)),
95+
"200a3b5c10d".to_string()
96+
)
97+
}
98+
#[test]
99+
fn decode_empty() {
100+
assert_eq!(
101+
(run_length_decoding("".to_string())),
102+
"String is Empty!".to_string()
103+
)
104+
}
105+
106+
#[test]
107+
fn decode_identical_character() {
108+
assert_eq!(
109+
(run_length_decoding("10a".to_string())),
110+
"aaaaaaaaaa".to_string()
111+
)
112+
}
113+
#[test]
114+
fn decode_continuous_character() {
115+
assert_eq!(
116+
(run_length_decoding("1a1b1c1d1e1f1g1h1i1j1k".to_string())),
117+
"abcdefghijk".to_string()
118+
)
119+
}
120+
121+
#[test]
122+
fn decode_random_character() {
123+
assert_eq!(
124+
(run_length_decoding("5a3b5c10d".to_string())),
125+
"aaaaabbbcccccdddddddddd".to_string()
126+
)
127+
}
128+
129+
#[test]
130+
fn decode_long_character() {
131+
assert_eq!(
132+
(run_length_decoding(
133+
"200a3b5c10d".to_string()
134+
)),
135+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbcccccdddddddddd".to_string()
136+
)
137+
}
138+
}

0 commit comments

Comments
 (0)