From 51be6aad33255e5f3fe201294875659dde4a18dc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 23:52:19 +0530 Subject: [PATCH 1/3] docs: update DIRECTORY.md (#2754) Co-authored-by: github-actions[bot] --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index b78662887c2..79eb258c16f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -19,6 +19,7 @@ * [Count Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_set_bits.cpp) * [Count Of Trailing Ciphers In Factorial N](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_trailing_ciphers_in_factorial_n.cpp) * [Find Non Repeating Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/find_non_repeating_number.cpp) + * [Gray Code](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/gray_code.cpp) * [Hamming Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/hamming_distance.cpp) * [Next Higher Number With Same Number Of Set Bits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/next_higher_number_with_same_number_of_set_bits.cpp) * [Power Of 2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/power_of_2.cpp) @@ -161,6 +162,7 @@ ## Greedy Algorithms * [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp) * [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp) + * [Gale Shapley](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/gale_shapley.cpp) * [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp) * [Jump Game](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jump_game.cpp) * [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/knapsack.cpp) @@ -377,6 +379,7 @@ * [Pigeonhole Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/pigeonhole_sort.cpp) * [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort.cpp) * [Quick Sort 3](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort_3.cpp) + * [Quick Sort Iterative](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/quick_sort_iterative.cpp) * [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/radix_sort.cpp) * [Radix Sort2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/radix_sort2.cpp) * [Random Pivot Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/sorting/random_pivot_quick_sort.cpp) From 0ecb6bd28a8a6b5ffc0edcad34ac036647d2259f Mon Sep 17 00:00:00 2001 From: jiya <122276932+jiya10208@users.noreply.github.com> Date: Sat, 5 Oct 2024 08:08:23 +0530 Subject: [PATCH 2/3] docs: reword binary search (#2752) * Update binary_search.cpp making some correction in the theory of binary search * Update search/binary_search.cpp Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --------- Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com> --- search/binary_search.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/search/binary_search.cpp b/search/binary_search.cpp index 5e455dd17e3..bed938b290c 100644 --- a/search/binary_search.cpp +++ b/search/binary_search.cpp @@ -4,8 +4,8 @@ * algorithm](https://en.wikipedia.org/wiki/Binary_search_algorithm) * @details * Binary search is a search algorithm that finds the position of a target value - * within a sorted array. Binary search compares the target value to the middle - * element of the array. If they are not equal, the half in which the target + * within a sorted array.Just like looking for a word in a dictionary, in binary search we compare the target value to the middle + * element of the array. If they are not equal, then the half in which the target * cannot lie is eliminated and the search continues on the remaining half, * again taking the middle element to compare to the target value, and repeating * this until the target value is found. If the search ends with the remaining @@ -13,7 +13,7 @@ * * ### Implementation * - * Binary search works on sorted arrays. Binary search begins by comparing an + * Binary search works on sorted arrays. It begins by comparing an * element in the middle of the array with the target value. If the target value * matches the element, its position in the array is returned. If the target * value is less than the element, the search continues in the lower half of @@ -28,6 +28,7 @@ * Worst-case time complexity O(log n) * Best-case time complexity O(1) * Average time complexity O(log n) + * space complexity 0(1) * Worst-case space complexity 0(1) * * @author [Lajat Manekar](https://github.com/Lazeeez) From 60093d70ab46eba45cc89b652986bec3bfdbdd9d Mon Sep 17 00:00:00 2001 From: Amine Ghoussaini <54037376+aminegh20@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:52:02 +0300 Subject: [PATCH 3/3] feat: add duval's algorithm (#2725) * feat: Add Duval's algorithm for the lexicographically smallest rotation in a sequence. * fixes. * fixes. --- strings/duval.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 strings/duval.cpp diff --git a/strings/duval.cpp b/strings/duval.cpp new file mode 100644 index 00000000000..9304da0c06f --- /dev/null +++ b/strings/duval.cpp @@ -0,0 +1,118 @@ +/** + * @file duval.cpp + * @brief Implementation of [Duval's algorithm](https://en.wikipedia.org/wiki/Lyndon_word). + * + * @details + * Duval's algorithm is an algorithm to find the lexicographically smallest + * rotation of a string. It is based on the concept of Lyndon words. + * Lyndon words are defined as the lexicographically smallest string in a + * rotation equivalence class. A rotation equivalence class is a set of strings + * that can be obtained by rotating a string. For example, the rotation + * equivalence class of "abc" is {"abc", "bca", "cab"}. The lexicographically + * smallest string in this class is "abc". + * + * Duval's algorithm works by iterating over the string and finding the + * smallest rotation of the string that is a Lyndon word. This is done by + * comparing the string with its suffixes and finding the smallest suffix that + * is lexicographically smaller than the string. This suffix is then added to + * the result and the process is repeated with the remaining string. + * The algorithm has a time complexity of O(n) where n is the length of the + * string. + * + * @note While Lyndon words are described in the context of strings, + * Duval's algorithm can be used to find the lexicographically smallest cyclic + * shift of any sequence of comparable elements. + * + * @author [Amine Ghoussaini](https://github.com/aminegh20) +*/ + +#include /// for std::array +#include /// for assert +#include /// for std::size_t +#include /// for std::deque +#include /// for std::cout and std::endl +#include /// for std::string +#include /// for std::vector + +/** + * @brief string manipulation algorithms + * @namespace + */ +namespace string { +/** + * @brief Find the lexicographically smallest cyclic shift of a sequence. + * @tparam T type of the sequence + * @param s the sequence + * @returns the 0-indexed position of the least cyclic shift of the sequence + */ +template +size_t duval(const T& s) { + size_t n = s.size(); + size_t i = 0, ans = 0; + while (i < n) { + ans = i; + size_t j = i + 1, k = i; + while (j < (n + n) && s[j % n] >= s[k % n]) { + if (s[k % n] < s[j % n]) { + k = i; + } else { + k++; + } + j++; + } + while (i <= k) { + i += j - k; + } + } + return ans; + // returns 0-indexed position of the least cyclic shift +} + +} // namespace string + +/** + * @brief self test implementation + * returns void + */ +static void test() { + using namespace string; + + // Test 1 + std::string s1 = "abcab"; + assert(duval(s1) == 3); + + // Test 2 + std::string s2 = "011100"; + assert(duval(s2) == 4); + + // Test 3 + std::vector v = {5, 2, 1, 3, 4}; + assert(duval(v) == 2); + + // Test 4 + std::array a = {1, 2, 3, 4, 5}; + assert(duval(a) == 0); + + // Test 5 + std::deque d = {'a', 'z', 'c', 'a', 'b'}; + assert(duval(d) == 3); + + // Test 6 + std::string s3; + assert(duval(s3) == 0); + + // Test 7 + std::vector v2 = {5, 2, 1, 3, -4}; + assert(duval(v2) == 4); + + std::cout << "All tests passed!" << std::endl; +} + +/** + * @brief main function + * @returns 0 on exit + */ +int main() { + test(); // run self test implementations + return 0; +}