From a83d0cf8e998651da31d5dbb7edc96d660084bd7 Mon Sep 17 00:00:00 2001 From: WoWL17 Date: Fri, 7 Apr 2023 15:44:40 +0200 Subject: [PATCH] feat: add well-formed parentheses generator --- backtracking/generate_parentheses.cpp | 97 +++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 backtracking/generate_parentheses.cpp diff --git a/backtracking/generate_parentheses.cpp b/backtracking/generate_parentheses.cpp new file mode 100644 index 00000000000..6c22133331d --- /dev/null +++ b/backtracking/generate_parentheses.cpp @@ -0,0 +1,97 @@ +/** + * @file + * @brief Generates all combinations of well-formed parentheses. + * + * @details a sequence of parentheses is well-formed if each opening parentheses + has a corresponding closing parenthesis + * and the closing parentheses are correctly ordered + * + * @author [Giuseppe Coco](https://github.com/WoWS17) + + */ + +#include +#include +#include + +class generate_parentheses { + private: + std::vector res; // Contains all possible valid patterns + + /** + * @brief function that implements backtracking + * + * @param str string build during backtracking + * @param n number of pairs of parentheses + * @param closed number of closed parentheses + * @param open number of open parentheses + */ + + void makeStrings(std::string str, int n, int closed, int open) { + if (closed > open) // We can never have more closed than open + return; + + if (str.length() == 2 * n and + closed != open) // closed and open must be the same + return; + + if (str.length() == 2 * n) { + res.push_back(str); + return; + } + + makeStrings(str + ')', n, closed + 1, open); + makeStrings(str + '(', n, closed, open + 1); + } + + public: + /** + * @brief wrapper interface + * + * @param n number of pairs of parentheses + * @return all well-formed pattern of parentheses + */ + std::vector generate_parenthesis(int n) { + res.clear(); + std::string str = "("; + makeStrings(str, n, 0, 1); + return res; + } +}; + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + int n; + std::vector patterns; + generate_parentheses p; + + n = 1; + patterns = {{"()"}}; + assert(p.generate_parenthesis(n) == patterns); + + n = 3; + patterns = {{"()()()"}, {"()(())"}, {"(())()"}, {"(()())"}, {"((()))"}}; + + assert(p.generate_parenthesis(n) == patterns); + + n = 4; + patterns = {{"()()()()"}, {"()()(())"}, {"()(())()"}, {"()(()())"}, + {"()((()))"}, {"(())()()"}, {"(())(())"}, {"(()())()"}, + {"(()()())"}, {"(()(()))"}, {"((()))()"}, {"((())())"}, + {"((()()))"}, {"(((())))"}}; + assert(p.generate_parenthesis(n) == patterns); + + std::cout << "All tests passed\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); + return 0; +} \ No newline at end of file