Skip to content

Commit 8674596

Browse files
sozelfistvil02
andcommitted
Implement Parentheses Generator using Backtracking Strategy (#713)
* chore: add `parentheses_generator.rs` to DIRECTORY.md * feat: implement Parentheses Generator algorithm * chore: rename `open` to `open_count`, `close` to `close_count` * chore: change `u32` to `usize` * ref: eliminate the need for mutability * chore: handle case where `n = 0` * chore: fix typos in docstring * style: simplify logic --------- Co-authored-by: Piotr Idzik <[email protected]>
1 parent 5c2e0c0 commit 8674596

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* [All Combination Of Size K](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/all_combination_of_size_k.rs)
66
* [Knight Tour](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/knight_tour.rs)
77
* [N Queens](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/n_queens.rs)
8+
* [Parentheses Generator](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/parentheses_generator.rs)
89
* [Permutations](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/permutations.rs)
910
* [Sudoku](https://github.com/TheAlgorithms/Rust/blob/master/src/backtracking/sudoku.rs)
1011
* Big Integer

src/backtracking/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
mod all_combination_of_size_k;
22
mod knight_tour;
33
mod n_queens;
4+
mod parentheses_generator;
45
mod permutations;
56
mod sudoku;
67

78
pub use all_combination_of_size_k::generate_all_combinations;
89
pub use knight_tour::find_knight_tour;
910
pub use n_queens::n_queens_solver;
11+
pub use parentheses_generator::generate_parentheses;
1012
pub use permutations::permute;
1113
pub use sudoku::sudoku_solver;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/// Generates all combinations of well-formed parentheses given a non-negative integer `n`.
2+
///
3+
/// This function uses backtracking to generate all possible combinations of well-formed
4+
/// parentheses. The resulting combinations are returned as a vector of strings.
5+
///
6+
/// # Arguments
7+
///
8+
/// * `n` - A non-negative integer representing the number of pairs of parentheses.
9+
pub fn generate_parentheses(n: usize) -> Vec<String> {
10+
let mut result = Vec::new();
11+
if n > 0 {
12+
generate("", 0, 0, n, &mut result);
13+
}
14+
result
15+
}
16+
17+
/// Helper function for generating parentheses recursively.
18+
///
19+
/// This function is called recursively to build combinations of well-formed parentheses.
20+
/// It tracks the number of open and close parentheses added so far and adds a new parenthesis
21+
/// if it's valid to do so.
22+
///
23+
/// # Arguments
24+
///
25+
/// * `current` - The current string of parentheses being built.
26+
/// * `open_count` - The count of open parentheses in the current string.
27+
/// * `close_count` - The count of close parentheses in the current string.
28+
/// * `n` - The total number of pairs of parentheses to be generated.
29+
/// * `result` - A mutable reference to the vector storing the generated combinations.
30+
fn generate(
31+
current: &str,
32+
open_count: usize,
33+
close_count: usize,
34+
n: usize,
35+
result: &mut Vec<String>,
36+
) {
37+
if current.len() == (n * 2) {
38+
result.push(current.to_string());
39+
return;
40+
}
41+
42+
if open_count < n {
43+
let new_str = current.to_string() + "(";
44+
generate(&new_str, open_count + 1, close_count, n, result);
45+
}
46+
47+
if close_count < open_count {
48+
let new_str = current.to_string() + ")";
49+
generate(&new_str, open_count, close_count + 1, n, result);
50+
}
51+
}
52+
53+
#[cfg(test)]
54+
mod tests {
55+
use super::*;
56+
57+
macro_rules! generate_parentheses_tests {
58+
($($name:ident: $test_case:expr,)*) => {
59+
$(
60+
#[test]
61+
fn $name() {
62+
let (n, expected_result) = $test_case;
63+
assert_eq!(generate_parentheses(n), expected_result);
64+
}
65+
)*
66+
};
67+
}
68+
69+
generate_parentheses_tests! {
70+
test_generate_parentheses_0: (0, Vec::<String>::new()),
71+
test_generate_parentheses_1: (1, vec!["()"]),
72+
test_generate_parentheses_2: (2, vec!["(())", "()()"]),
73+
test_generate_parentheses_3: (3, vec!["((()))", "(()())", "(())()", "()(())", "()()()"]),
74+
test_generate_parentheses_4: (4, vec!["(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()"]),
75+
}
76+
}

0 commit comments

Comments
 (0)