Skip to content

Commit 114e01f

Browse files
authored
Refactor is_subsequence Implemenation (#819)
ref: refactor is subsequence implemenation
1 parent 274ca13 commit 114e01f

File tree

1 file changed

+58
-20
lines changed

1 file changed

+58
-20
lines changed
+58-20
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,71 @@
1-
// Given two strings str1 and str2, return true if str1 is a subsequence of str2, or false otherwise.
2-
// A subsequence of a string is a new string that is formed from the original string
3-
// by deleting some (can be none) of the characters without disturbing the relative
4-
// positions of the remaining characters.
5-
// (i.e., "ace" is a subsequence of "abcde" while "aec" is not).
6-
pub fn is_subsequence(str1: &str, str2: &str) -> bool {
7-
let mut it1 = 0;
8-
let mut it2 = 0;
1+
//! A module for checking if one string is a subsequence of another string.
2+
//!
3+
//! A subsequence is formed by deleting some (can be none) of the characters
4+
//! from the original string without disturbing the relative positions of the
5+
//! remaining characters. This module provides a function to determine if
6+
//! a given string is a subsequence of another string.
97
10-
let byte1 = str1.as_bytes();
11-
let byte2 = str2.as_bytes();
8+
/// Checks if `sub` is a subsequence of `main`.
9+
///
10+
/// # Arguments
11+
///
12+
/// * `sub` - A string slice that may be a subsequence.
13+
/// * `main` - A string slice that is checked against.
14+
///
15+
/// # Returns
16+
///
17+
/// Returns `true` if `sub` is a subsequence of `main`, otherwise returns `false`.
18+
pub fn is_subsequence(sub: &str, main: &str) -> bool {
19+
let mut sub_iter = sub.chars().peekable();
20+
let mut main_iter = main.chars();
1221

13-
while it1 < str1.len() && it2 < str2.len() {
14-
if byte1[it1] == byte2[it2] {
15-
it1 += 1;
22+
while let Some(&sub_char) = sub_iter.peek() {
23+
match main_iter.next() {
24+
Some(main_char) if main_char == sub_char => {
25+
sub_iter.next();
26+
}
27+
None => return false,
28+
_ => {}
1629
}
17-
18-
it2 += 1;
1930
}
2031

21-
it1 == str1.len()
32+
true
2233
}
2334

2435
#[cfg(test)]
2536
mod tests {
2637
use super::*;
2738

28-
#[test]
29-
fn test() {
30-
assert!(is_subsequence("abc", "ahbgdc"));
31-
assert!(!is_subsequence("axc", "ahbgdc"));
39+
macro_rules! subsequence_tests {
40+
($($name:ident: $test_case:expr,)*) => {
41+
$(
42+
#[test]
43+
fn $name() {
44+
let (sub, main, expected) = $test_case;
45+
assert_eq!(is_subsequence(sub, main), expected);
46+
}
47+
)*
48+
};
49+
}
50+
51+
subsequence_tests! {
52+
test_empty_subsequence: ("", "ahbgdc", true),
53+
test_empty_strings: ("", "", true),
54+
test_non_empty_sub_empty_main: ("abc", "", false),
55+
test_subsequence_found: ("abc", "ahbgdc", true),
56+
test_subsequence_not_found: ("axc", "ahbgdc", false),
57+
test_longer_sub: ("abcd", "abc", false),
58+
test_single_character_match: ("a", "ahbgdc", true),
59+
test_single_character_not_match: ("x", "ahbgdc", false),
60+
test_subsequence_at_start: ("abc", "abchello", true),
61+
test_subsequence_at_end: ("cde", "abcde", true),
62+
test_same_characters: ("aaa", "aaaaa", true),
63+
test_interspersed_subsequence: ("ace", "abcde", true),
64+
test_different_chars_in_subsequence: ("aceg", "abcdef", false),
65+
test_single_character_in_main_not_match: ("a", "b", false),
66+
test_single_character_in_main_match: ("b", "b", true),
67+
test_subsequence_with_special_chars: ("a1!c", "a1!bcd", true),
68+
test_case_sensitive: ("aBc", "abc", false),
69+
test_subsequence_with_whitespace: ("hello world", "h e l l o w o r l d", true),
3270
}
3371
}

0 commit comments

Comments
 (0)