From 0d766b0f8abc24bf40e881ddb55f276652ba9827 Mon Sep 17 00:00:00 2001 From: realstealthninja <68815218+realstealthninja@users.noreply.github.com> Date: Mon, 4 Nov 2024 18:00:20 +0530 Subject: [PATCH] feat: update to CXX standard 17 and add CMakeLists file to directories without them (#2746) * chore: add cache and build comment to git ignore * fix: add cmakelists to dynamic programming * fix: add cmakelists to greedy_algorithms * fix: add cmakelists to operations_on_datastructures * fix: add cmakelists to range_queries * fix: add `dynamic_programmin`, `greedy_algorithms`, `range_queries` and `operations_on_datastructures` subdirectories to cmakelists.txt * fix: init of transform_reduce in dynamic_programming * fix: add an include for functional in catalan_numbers * chore: bump CXX standard to 20 * revert: bump CXX standard to 20 * chore: bump c++ version to 17 and add justification Arm supports c++ 17 Esp32 supports c++ 23 decision was made to be 17 because it seemed to offer the best combatability * fix: compilation error in catalan numbers * fix: add header to longest increasing subsequence nlogn * fix: add cmath & algorithm header to mo.cpp * fix: remove register key word from fast integer * fix: replace using namespace std with std::cin and std::cout * docs: typo in c++17 * fix: memory leak in bellman_ford * fix: typo in bellman_ford * fix: typo in word_break * fix: dynamic array in coin_change * fix dynamic array in egg_dropping puzzle * chore: remove unnecessary comment * fix: add vla to be an error * chore: add extra warnings * fix: use add_compile options instead of set() * fix: compile options are not strings * fix: vla in floyd_warshall * fix: vla in egg_dropping_puzzel * fix: vla in coin_change * fix: vla in edit_distance * fix: vla in floyd_warshall * feat: remove kadane and replace it with kadane2 * fix: vla in longest_common_subsequence * fix: int overflow in floyd_warshall * fix: vla in lisnlogn * fix: use const vector& instead of array * fix: use dynamic array instead of vla in knapsack * fix: use of and in msvc is unsupported by default adding permissive flag fixes it * test: make executables the tests themselves * Revert "test: make executables the tests themselves" This reverts commit 7a16c31c4e7fa2d472f0713d4fc97d48c9be6838. * fix: make dist constant in print * fix: namespace issue in unbounded_0_1 * fix: include cstdint to fix compilation --- .gitignore | 4 + CMakeLists.txt | 17 +- README.md | 2 +- dynamic_programming/CMakeLists.txt | 18 ++ dynamic_programming/abbreviation.cpp | 1 + ...ber.cpp => armstrong_number_templated.cpp} | 0 dynamic_programming/bellman_ford.cpp | 12 +- dynamic_programming/catalan_numbers.cpp | 13 +- dynamic_programming/coin_change.cpp | 3 +- dynamic_programming/cut_rod.cpp | 13 +- dynamic_programming/edit_distance.cpp | 3 +- dynamic_programming/egg_dropping_puzzle.cpp | 5 +- dynamic_programming/floyd_warshall.cpp | 15 +- dynamic_programming/house_robber.cpp | 2 +- dynamic_programming/kadane.cpp | 85 +++++++--- dynamic_programming/kadane2.cpp | 74 --------- .../longest_common_subsequence.cpp | 3 +- .../longest_increasing_subsequence.cpp | 1 + ... longest_increasing_subsequence_nlogn.cpp} | 6 +- dynamic_programming/minimum_edit_distance.cpp | 139 +++++++++------- dynamic_programming/partition_problem.cpp | 2 +- ...{subset_sum.cpp => subset_sum_dynamic.cpp} | 0 .../unbounded_0_1_knapsack.cpp | 154 ++++++++++-------- dynamic_programming/word_break.cpp | 2 +- greedy_algorithms/CMakeLists.txt | 18 ++ .../{dijkstra.cpp => dijkstra_greedy.cpp} | 0 greedy_algorithms/knapsack.cpp | 4 +- operations_on_datastructures/CMakeLists.txt | 15 ++ .../circular_queue_using_array.cpp | 3 +- .../trie_multiple_search.cpp | 7 +- others/fast_integer_input.cpp | 2 +- range_queries/CMakeLists.txt | 18 ++ range_queries/mo.cpp | 3 + range_queries/segtree.cpp | 1 + ...ble.cpp => sparse_table_range_queries.cpp} | 0 35 files changed, 377 insertions(+), 268 deletions(-) create mode 100644 dynamic_programming/CMakeLists.txt rename dynamic_programming/{armstrong_number.cpp => armstrong_number_templated.cpp} (100%) delete mode 100644 dynamic_programming/kadane2.cpp rename dynamic_programming/{longest_increasing_subsequence_(nlogn).cpp => longest_increasing_subsequence_nlogn.cpp} (92%) rename dynamic_programming/{subset_sum.cpp => subset_sum_dynamic.cpp} (100%) create mode 100644 greedy_algorithms/CMakeLists.txt rename greedy_algorithms/{dijkstra.cpp => dijkstra_greedy.cpp} (100%) create mode 100644 operations_on_datastructures/CMakeLists.txt create mode 100644 range_queries/CMakeLists.txt rename range_queries/{sparse_table.cpp => sparse_table_range_queries.cpp} (100%) diff --git a/.gitignore b/.gitignore index a94731cc2ed..c4951fe97b1 100644 --- a/.gitignore +++ b/.gitignore @@ -34,5 +34,9 @@ a.out *.out *.app +# Cache +.cache/ + +# Build build/ git_diff.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index cca1b54649b..95038fbab78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,16 +5,17 @@ project(Algorithms_in_C++ DESCRIPTION "Set of algorithms implemented in C++." ) -# set(CMAKE_CXX_CPPLINT "~/anaconda3/bin/cpplint --filter=-legal/copyright --std=c++11") -# find_program(CLANG_FORMAT "clang-format") - -set(CMAKE_CXX_STANDARD 11) +# C++ standard +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Additional warnings and errors if(MSVC) - # set(CMAKE_CXX_STANDARD 14) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) -endif(MSVC) + add_compile_options(/W4 /permissive-) +else() + add_compile_options(-Wall -Wextra -Wno-register -Werror=vla) +endif() option(USE_OPENMP "flag to use OpenMP for multithreading" ON) if(USE_OPENMP) @@ -38,6 +39,10 @@ add_subdirectory(graphics) add_subdirectory(probability) add_subdirectory(backtracking) add_subdirectory(bit_manipulation) +add_subdirectory(dynamic_programming) +add_subdirectory(greedy_algorithms) +add_subdirectory(range_queries) +add_subdirectory(operations_on_datastructures) add_subdirectory(data_structures) add_subdirectory(machine_learning) add_subdirectory(numerical_methods) diff --git a/README.md b/README.md index 5ad49b18473..9f32c07b70e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This repository is a collection of open-source implementation of a variety of al * Well documented source code with detailed explanations provide a valuable resource for educators and students alike. * Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus, the fundamentals of the algorithms can be studied in much depth. * Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS, and Ubuntu (Linux) using MSVC 19 2022, AppleClang 14.0.0, and GNU 11.3.0 respectively. -* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc. with little to no changes. +* Strict adherence to [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) standard ensures portability of code to embedded systems as well like [ESP32](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/cplusplus.html#c-language-standard), [ARM Cortex](https://developer.arm.com/documentation/101458/2404/Standards-support/Supported-C-C---standards-in-Arm-C-C---Compiler), etc. with little to no changes. * Self-checks within programs ensure correct implementations with confidence. * Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications. diff --git a/dynamic_programming/CMakeLists.txt b/dynamic_programming/CMakeLists.txt new file mode 100644 index 00000000000..bcf0a990013 --- /dev/null +++ b/dynamic_programming/CMakeLists.txt @@ -0,0 +1,18 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + if(OpenMP_CXX_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_CXX) + endif() + install(TARGETS ${testname} DESTINATION "bin/dynamic_programming") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/dynamic_programming/abbreviation.cpp b/dynamic_programming/abbreviation.cpp index 9ee4dc27436..1da8d30f83d 100644 --- a/dynamic_programming/abbreviation.cpp +++ b/dynamic_programming/abbreviation.cpp @@ -24,6 +24,7 @@ */ #include /// for `assert` +#include /// for `std::uint32_t` #include /// for IO operations #include /// for `std::string` library #include /// for `std::vector` STL library diff --git a/dynamic_programming/armstrong_number.cpp b/dynamic_programming/armstrong_number_templated.cpp similarity index 100% rename from dynamic_programming/armstrong_number.cpp rename to dynamic_programming/armstrong_number_templated.cpp diff --git a/dynamic_programming/bellman_ford.cpp b/dynamic_programming/bellman_ford.cpp index c96f3fd8eea..a55596d41d1 100644 --- a/dynamic_programming/bellman_ford.cpp +++ b/dynamic_programming/bellman_ford.cpp @@ -1,5 +1,6 @@ -#include +#include #include +#include using namespace std; @@ -13,13 +14,13 @@ class Edge { class Graph { public: int vertexNum, edgeNum; - Edge *edges; + std::vector edges; // Constructs a graph with V vertices and E edges Graph(int V, int E) { this->vertexNum = V; this->edgeNum = E; - this->edges = (Edge *)malloc(E * sizeof(Edge)); + this->edges.reserve(E); } // Adds the given edge to the graph @@ -36,7 +37,7 @@ class Graph { }; // Utility function to print distances -void print(int dist[], int V) { +void print(const std::vector& dist, int V) { cout << "\nVertex Distance" << endl; for (int i = 0; i < V; i++) { if (dist[i] != INT_MAX) @@ -52,7 +53,8 @@ void print(int dist[], int V) { void BellmanFord(Graph graph, int src) { int V = graph.vertexNum; int E = graph.edgeNum; - int dist[V]; + std::vector dist; + dist.reserve(E); // Initialize distances array as INF for all except source // Intialize source as zero diff --git a/dynamic_programming/catalan_numbers.cpp b/dynamic_programming/catalan_numbers.cpp index c99ea00265c..9c737b466cb 100644 --- a/dynamic_programming/catalan_numbers.cpp +++ b/dynamic_programming/catalan_numbers.cpp @@ -9,11 +9,12 @@ https://oeis.org/A000108/ */ -#include /// for assert -#include /// for std::uint64_t -#include /// for std::size_t -#include /// for std::transform_reduce -#include /// for std::vector +#include /// for assert +#include /// for std::uint64_t +#include /// for std::size_t +#include /// for std::plus & std::multiplies +#include /// for std::transform_reduce +#include /// for std::vector /** * @brief computes and caches Catalan numbers @@ -24,7 +25,7 @@ class catalan_numbers { value_type compute_next() { return std::transform_reduce(known.begin(), known.end(), known.rbegin(), - static_cast(), std::plus<>(), + static_cast(0), std::plus<>(), std::multiplies<>()); } diff --git a/dynamic_programming/coin_change.cpp b/dynamic_programming/coin_change.cpp index 8c8fc3dfb68..f4c0541fde8 100644 --- a/dynamic_programming/coin_change.cpp +++ b/dynamic_programming/coin_change.cpp @@ -1,11 +1,12 @@ #include #include +#include using namespace std; // Function to find the Minimum number of coins required to get Sum S int findMinCoins(int arr[], int n, int N) { // dp[i] = no of coins required to get a total of i - int dp[N + 1]; + std::vector dp(N + 1); // 0 coins are needed for 0 sum diff --git a/dynamic_programming/cut_rod.cpp b/dynamic_programming/cut_rod.cpp index c365be4fcaf..cb7a247c2e2 100644 --- a/dynamic_programming/cut_rod.cpp +++ b/dynamic_programming/cut_rod.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include /** * @namespace dynamic_programming @@ -70,8 +71,8 @@ int maxProfitByCuttingRod(const std::array &price, const uint64_t &n) { */ static void test() { // Test 1 - const int16_t n1 = 8; // size of rod - std::array price1 = {1,2,4,6,8,45,21,9}; // price array + const int16_t n1 = 8; // size of rod + std::array price1 = {1, 2, 4, 6, 8, 45, 21, 9}; // price array const int64_t max_profit1 = dynamic_programming::cut_rod::maxProfitByCuttingRod(price1, n1); const int64_t expected_max_profit1 = 47; @@ -86,15 +87,15 @@ static void test() { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50}; - const int64_t max_profit2= + const int64_t max_profit2 = dynamic_programming::cut_rod::maxProfitByCuttingRod(price2, n2); const int32_t expected_max_profit2 = 90; assert(max_profit2 == expected_max_profit2); std::cout << "Maximum profit with " << n2 << " inch road is " << max_profit2 << std::endl; - // Test 3 - const int16_t n3 = 5; // size of rod - std::array price3 = {2,9,17,23,45}; // price array + // Test 3 + const int16_t n3 = 5; // size of rod + std::array price3 = {2, 9, 17, 23, 45}; // price array const int64_t max_profit3 = dynamic_programming::cut_rod::maxProfitByCuttingRod(price3, n3); const int64_t expected_max_profit3 = 45; diff --git a/dynamic_programming/edit_distance.cpp b/dynamic_programming/edit_distance.cpp index 889b080cb93..02dae8ca90e 100644 --- a/dynamic_programming/edit_distance.cpp +++ b/dynamic_programming/edit_distance.cpp @@ -13,6 +13,7 @@ #include #include +#include using namespace std; int min(int x, int y, int z) { return min(min(x, y), z); } @@ -46,7 +47,7 @@ int editDist(string str1, string str2, int m, int n) { */ int editDistDP(string str1, string str2, int m, int n) { // Create Table for SubProblems - int dp[m + 1][n + 1]; + std::vector > dp(m + 1, std::vector(n + 1)); // Fill d[][] in bottom up manner for (int i = 0; i <= m; i++) { diff --git a/dynamic_programming/egg_dropping_puzzle.cpp b/dynamic_programming/egg_dropping_puzzle.cpp index 7a769ea472e..e83f14af84b 100644 --- a/dynamic_programming/egg_dropping_puzzle.cpp +++ b/dynamic_programming/egg_dropping_puzzle.cpp @@ -4,10 +4,13 @@ #include #include +#include + using namespace std; int eggDrop(int n, int k) { - int eggFloor[n + 1][k + 1]; + std::vector > eggFloor(n + 1, std::vector(k + 1)); + int result; for (int i = 1; i <= n; i++) { diff --git a/dynamic_programming/floyd_warshall.cpp b/dynamic_programming/floyd_warshall.cpp index d193ebbd589..c314bbf3976 100644 --- a/dynamic_programming/floyd_warshall.cpp +++ b/dynamic_programming/floyd_warshall.cpp @@ -1,6 +1,7 @@ #include +#include #include -#include +#include using std::cin; using std::cout; @@ -24,7 +25,9 @@ class Graph { } ~Graph() { - for (int i = 0; i < vertexNum; i++) delete[] edges[i]; + for (int i = 0; i < vertexNum; i++) { + delete[] edges[i]; + } delete[] edges; } @@ -35,7 +38,7 @@ class Graph { }; // Utility function to print distances -void print(int dist[], int V) { +void print(const std::vector& dist, int V) { cout << "\nThe Distance matrix for Floyd - Warshall" << endl; for (int i = 0; i < V; i++) { for (int j = 0; j < V; j++) { @@ -52,8 +55,8 @@ void print(int dist[], int V) { // The main function that finds the shortest path from a vertex // to all other vertices using Floyd-Warshall Algorithm. void FloydWarshall(Graph graph) { - int V = graph.vertexNum; - int dist[V][V]; + std::size_t V = graph.vertexNum; + std::vector > dist(V, std::vector(V)); // Initialise distance array for (int i = 0; i < V; i++) @@ -76,7 +79,7 @@ void FloydWarshall(Graph graph) { dist[i][j] = dist[i][k] + dist[k][j]; // Convert 2d array to 1d array for print - int dist1d[V * V]; + std::vector dist1d(V * V); for (int i = 0; i < V; i++) for (int j = 0; j < V; j++) dist1d[i * V + j] = dist[i][j]; diff --git a/dynamic_programming/house_robber.cpp b/dynamic_programming/house_robber.cpp index 0d238b9c13d..806a0a7d63d 100644 --- a/dynamic_programming/house_robber.cpp +++ b/dynamic_programming/house_robber.cpp @@ -11,9 +11,9 @@ #include /// for assert #include /// for std::max +#include /// for std::uint32_t #include /// for io operations #include /// for std::vector - /** * @namespace dynamic_programming * @brief Dynamic Programming algorithms diff --git a/dynamic_programming/kadane.cpp b/dynamic_programming/kadane.cpp index b5272756bcf..d048d0d5b27 100644 --- a/dynamic_programming/kadane.cpp +++ b/dynamic_programming/kadane.cpp @@ -1,29 +1,74 @@ +/** + * @file + * @brief Implementation of [Kadane + * Algorithm](https://en.wikipedia.org/wiki/Kadane%27s_algorithm) + * + * @details + * Kadane algorithm is used to find the maximum sum subarray in an array and + * maximum sum subarray problem is the task of finding a contiguous subarray + * with the largest sum + * + * ### Algorithm + * The simple idea of the algorithm is to search for all positive + * contiguous segments of the array and keep track of maximum sum contiguous + * segment among all positive segments(curr_sum is used for this) + * Each time we get a positive sum we compare it with max_sum and update max_sum + * if it is greater than curr_sum + * + * @author [Ayush Singh](https://github.com/ayush523) + */ +#include #include #include - -int maxSubArraySum(int a[], int size) { - int max_so_far = INT_MIN, max_ending_here = 0; - - for (int i = 0; i < size; i++) { - max_ending_here = max_ending_here + a[i]; - if (max_so_far < max_ending_here) - max_so_far = max_ending_here; - - if (max_ending_here < 0) - max_ending_here = 0; +/** + * @namespace dynamic_programming + * @brief Dynamic Programming algorithms + */ +namespace dynamic_programming { +/** + * @namespace kadane + * @brief Functions for + * [Kadane](https://en.wikipedia.org/wiki/Kadane%27s_algorithm) algorithm. + */ +namespace kadane { +/** + * @brief maxSubArray function is used to calculate the maximum sum subarray + * and returns the value of maximum sum which is stored in the variable max_sum + * @tparam N number of array size + * @param n array where numbers are saved + * @returns the value of maximum subarray sum + */ +template +int maxSubArray(const std::array &n) { + int curr_sum = + 0; // declaring a variable named as curr_sum and initialized it to 0 + int max_sum = INT_MIN; // Initialized max_sum to INT_MIN + for (int i : n) { // for loop to iterate over the elements of the array + curr_sum += n[i]; + max_sum = std::max(max_sum, curr_sum); // getting the maximum value + curr_sum = std::max(curr_sum, 0); // updating the value of curr_sum } - return max_so_far; + return max_sum; // returning the value of max_sum } +} // namespace kadane +} // namespace dynamic_programming +/** + * @brief Main function + * @returns 0 on exit + */ int main() { - int n, i; - std::cout << "Enter the number of elements \n"; - std::cin >> n; - int a[n]; // NOLINT - for (i = 0; i < n; i++) { - std::cin >> a[i]; + const int N = 5; + std::array n{}; // declaring array + // taking values of elements from user + for (int i = 0; i < n.size(); i++) { + std::cout << "Enter value of n[" << i << "]" + << "\n"; + std::cin >> n[i]; } - int max_sum = maxSubArraySum(a, n); - std::cout << "Maximum contiguous sum is " << max_sum; + int max_sum = dynamic_programming::kadane::maxSubArray( + n); // calling maxSubArray function + std::cout << "Maximum subarray sum is " << max_sum; // Printing the answer + return 0; } diff --git a/dynamic_programming/kadane2.cpp b/dynamic_programming/kadane2.cpp deleted file mode 100644 index d048d0d5b27..00000000000 --- a/dynamic_programming/kadane2.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file - * @brief Implementation of [Kadane - * Algorithm](https://en.wikipedia.org/wiki/Kadane%27s_algorithm) - * - * @details - * Kadane algorithm is used to find the maximum sum subarray in an array and - * maximum sum subarray problem is the task of finding a contiguous subarray - * with the largest sum - * - * ### Algorithm - * The simple idea of the algorithm is to search for all positive - * contiguous segments of the array and keep track of maximum sum contiguous - * segment among all positive segments(curr_sum is used for this) - * Each time we get a positive sum we compare it with max_sum and update max_sum - * if it is greater than curr_sum - * - * @author [Ayush Singh](https://github.com/ayush523) - */ -#include -#include -#include -/** - * @namespace dynamic_programming - * @brief Dynamic Programming algorithms - */ -namespace dynamic_programming { -/** - * @namespace kadane - * @brief Functions for - * [Kadane](https://en.wikipedia.org/wiki/Kadane%27s_algorithm) algorithm. - */ -namespace kadane { -/** - * @brief maxSubArray function is used to calculate the maximum sum subarray - * and returns the value of maximum sum which is stored in the variable max_sum - * @tparam N number of array size - * @param n array where numbers are saved - * @returns the value of maximum subarray sum - */ -template -int maxSubArray(const std::array &n) { - int curr_sum = - 0; // declaring a variable named as curr_sum and initialized it to 0 - int max_sum = INT_MIN; // Initialized max_sum to INT_MIN - for (int i : n) { // for loop to iterate over the elements of the array - curr_sum += n[i]; - max_sum = std::max(max_sum, curr_sum); // getting the maximum value - curr_sum = std::max(curr_sum, 0); // updating the value of curr_sum - } - return max_sum; // returning the value of max_sum -} -} // namespace kadane -} // namespace dynamic_programming - -/** - * @brief Main function - * @returns 0 on exit - */ -int main() { - const int N = 5; - std::array n{}; // declaring array - // taking values of elements from user - for (int i = 0; i < n.size(); i++) { - std::cout << "Enter value of n[" << i << "]" - << "\n"; - std::cin >> n[i]; - } - int max_sum = dynamic_programming::kadane::maxSubArray( - n); // calling maxSubArray function - std::cout << "Maximum subarray sum is " << max_sum; // Printing the answer - - return 0; -} diff --git a/dynamic_programming/longest_common_subsequence.cpp b/dynamic_programming/longest_common_subsequence.cpp index 662c26ad2c3..89a57dc0e03 100644 --- a/dynamic_programming/longest_common_subsequence.cpp +++ b/dynamic_programming/longest_common_subsequence.cpp @@ -1,5 +1,6 @@ // Longest common subsequence - Dynamic Programming #include +#include using namespace std; void Print(int trace[20][20], int m, int n, string a) { @@ -18,7 +19,7 @@ void Print(int trace[20][20], int m, int n, string a) { int lcs(string a, string b) { int m = a.length(), n = b.length(); - int res[m + 1][n + 1]; + std::vector > res(m + 1, std::vector(n + 1)); int trace[20][20]; // fills up the arrays with zeros. diff --git a/dynamic_programming/longest_increasing_subsequence.cpp b/dynamic_programming/longest_increasing_subsequence.cpp index a93c139c428..8c8f97c438e 100644 --- a/dynamic_programming/longest_increasing_subsequence.cpp +++ b/dynamic_programming/longest_increasing_subsequence.cpp @@ -21,6 +21,7 @@ #include /// for assert #include /// for std::max +#include /// for std::uint64_t #include /// for IO operations #include /// for std::vector diff --git a/dynamic_programming/longest_increasing_subsequence_(nlogn).cpp b/dynamic_programming/longest_increasing_subsequence_nlogn.cpp similarity index 92% rename from dynamic_programming/longest_increasing_subsequence_(nlogn).cpp rename to dynamic_programming/longest_increasing_subsequence_nlogn.cpp index 5bc72345c23..b0a49d2dab0 100644 --- a/dynamic_programming/longest_increasing_subsequence_(nlogn).cpp +++ b/dynamic_programming/longest_increasing_subsequence_nlogn.cpp @@ -3,9 +3,11 @@ // tested on : https://cses.fi/problemset/task/1145/ #include +#include +#include using namespace std; -int LIS(int arr[], int n) { +int LIS(const std::vector& arr, int n) { set active; // The current built LIS. active.insert(arr[0]); // Loop through every element. @@ -31,7 +33,7 @@ int main(int argc, char const* argv[]) { int n; cout << "Enter size of array: "; cin >> n; - int a[n]; + std::vector a(n); cout << "Enter array elements: "; for (int i = 0; i < n; ++i) { cin >> a[i]; diff --git a/dynamic_programming/minimum_edit_distance.cpp b/dynamic_programming/minimum_edit_distance.cpp index db9dd665dfb..8664ccb4513 100644 --- a/dynamic_programming/minimum_edit_distance.cpp +++ b/dynamic_programming/minimum_edit_distance.cpp @@ -1,6 +1,8 @@ /** * @file - * @brief Implementation of [Minimum Edit Distance](https://en.wikipedia.org/wiki/Edit_distance) using Dynamic Programing + * @brief Implementation of [Minimum Edit + * Distance](https://en.wikipedia.org/wiki/Edit_distance) using Dynamic + * Programing * * @details * @@ -32,9 +34,11 @@ * @author [Nirjas Jakilim](github.com/nirzak) */ -#include /// for assert -#include /// for IO operations +#include /// for assert +#include /// for std::uint64_t +#include /// for IO operations #include /// for std::vector + /** * @namespace dynamic_programming * @brief Dynamic Programming algorithms @@ -44,7 +48,8 @@ namespace dynamic_programming { /** * @namespace Minimum Edit Distance - * @brief Implementation of [Minimum Edit Distance](https://en.wikipedia.org/wiki/Edit_distance) algorithm + * @brief Implementation of [Minimum Edit + * Distance](https://en.wikipedia.org/wiki/Edit_distance) algorithm */ namespace minimum_edit_distance { @@ -61,15 +66,14 @@ namespace minimum_edit_distance { * @returns z if `z` is the minimum value */ uint64_t min(uint64_t x, uint64_t y, uint64_t z) { - if (x <= y && x <= z) { - return x; /// returns x, if x is the minimum value - } - if (y <= x && y <= z) { - return y; /// returns y, if y is the minimum value - } - else { - return z; /// returns z if z is the minimum value - } + if (x <= y && x <= z) { + return x; /// returns x, if x is the minimum value + } + if (y <= x && y <= z) { + return y; /// returns y, if y is the minimum value + } else { + return z; /// returns z if z is the minimum value + } } /** @@ -85,42 +89,48 @@ uint64_t min(uint64_t x, uint64_t y, uint64_t z) { * @returns dp[m][n] the minimum cost of operations * needed to convert str1 to str2 */ -uint64_t editDistDP(std::string str1, std::string str2, uint64_t m, uint64_t n) { - /// Create a table to store results of subproblems - std::vector>dp(m+1, std::vector(n+1)); /// creasting 2D vector dp to store the results of subproblems +uint64_t editDistDP(std::string str1, std::string str2, uint64_t m, + uint64_t n) { + /// Create a table to store results of subproblems + std::vector> dp( + m + 1, + std::vector( + n + + 1)); /// creasting 2D vector dp to store the results of subproblems - /// Fill d[][] in bottom up manner - for (uint64_t i = 0; i <= m; i++) { - for (uint64_t j = 0; j <= n; j++) { - /// If first string is empty, only option is to - /// insert all characters of second string - if (i == 0) { - dp[i][j] = j; /// Minimum operations = j - } + /// Fill d[][] in bottom up manner + for (uint64_t i = 0; i <= m; i++) { + for (uint64_t j = 0; j <= n; j++) { + /// If first string is empty, only option is to + /// insert all characters of second string + if (i == 0) { + dp[i][j] = j; /// Minimum operations = j + } - /// If second string is empty, only option is to - /// remove all characters of second string - else if (j == 0) { - dp[i][j] = i; /// Minimum operations = i - } + /// If second string is empty, only option is to + /// remove all characters of second string + else if (j == 0) { + dp[i][j] = i; /// Minimum operations = i + } - /// If last characters are same, ignore last char - /// and recur for remaining string - else if (str1[i - 1] == str2[j - 1]) { - dp[i][j] = dp[i - 1][j - 1]; - } + /// If last characters are same, ignore last char + /// and recur for remaining string + else if (str1[i - 1] == str2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } - /// If the last character is different, consider all - /// possibilities and find the minimum - else { - dp[i][j] = 1 + min(dp[i][j - 1], // Insert - dp[i - 1][j], // Remove - dp[i - 1][j - 1]); // Replace - } + /// If the last character is different, consider all + /// possibilities and find the minimum + else { + dp[i][j] = 1 + min(dp[i][j - 1], // Insert + dp[i - 1][j], // Remove + dp[i - 1][j - 1]); // Replace + } + } } - } - return dp[m][n]; /// returning the minimum cost of operations needed to convert str1 to str2 + return dp[m][n]; /// returning the minimum cost of operations needed to + /// convert str1 to str2 } } // namespace minimum_edit_distance } // namespace dynamic_programming @@ -130,25 +140,28 @@ uint64_t editDistDP(std::string str1, std::string str2, uint64_t m, uint64_t n) * @returns void */ static void test() { - // 1st test - std::string str1 = "INTENTION"; // Sample input of 1st string - std::string str2 = "EXECUTION"; // Sample input of 2nd string - uint64_t expected_output1 = 5; // Expected minimum cost - uint64_t output1 = dynamic_programming::minimum_edit_distance::editDistDP( - str1, str2, str1.length(), str2.length()); // calling the editDistDP function and storing the result on output1 - assert(output1 == expected_output1); // comparing the output with the expected output - std::cout << "Minimum Number of Operations Required: " << output1 - << std::endl; + // 1st test + std::string str1 = "INTENTION"; // Sample input of 1st string + std::string str2 = "EXECUTION"; // Sample input of 2nd string + uint64_t expected_output1 = 5; // Expected minimum cost + uint64_t output1 = dynamic_programming::minimum_edit_distance::editDistDP( + str1, str2, str1.length(), + str2.length()); // calling the editDistDP function and storing the + // result on output1 + assert(output1 == + expected_output1); // comparing the output with the expected output + std::cout << "Minimum Number of Operations Required: " << output1 + << std::endl; - // 2nd test - std::string str3 = "SATURDAY"; - std::string str4 = "SUNDAY"; - uint64_t expected_output2 = 3; - uint64_t output2 = dynamic_programming::minimum_edit_distance::editDistDP( - str3, str4, str3.length(), str4.length()); - assert(output2 == expected_output2); - std::cout << "Minimum Number of Operations Required: " << output2 - << std::endl; + // 2nd test + std::string str3 = "SATURDAY"; + std::string str4 = "SUNDAY"; + uint64_t expected_output2 = 3; + uint64_t output2 = dynamic_programming::minimum_edit_distance::editDistDP( + str3, str4, str3.length(), str4.length()); + assert(output2 == expected_output2); + std::cout << "Minimum Number of Operations Required: " << output2 + << std::endl; } /** @@ -158,6 +171,6 @@ static void test() { * @returns 0 on exit */ int main(int argc, char *argv[]) { - test(); // run self-test implementations - return 0; + test(); // run self-test implementations + return 0; } diff --git a/dynamic_programming/partition_problem.cpp b/dynamic_programming/partition_problem.cpp index 586a1800ba3..0dbfaa1d740 100644 --- a/dynamic_programming/partition_problem.cpp +++ b/dynamic_programming/partition_problem.cpp @@ -28,10 +28,10 @@ * *******************************************************************************/ #include /// for assert +#include /// for std::uint64_t #include /// for IO Operations #include /// for std::accumulate #include /// for std::vector - /****************************************************************************** * @namespace dp * @brief Dynamic programming algorithms diff --git a/dynamic_programming/subset_sum.cpp b/dynamic_programming/subset_sum_dynamic.cpp similarity index 100% rename from dynamic_programming/subset_sum.cpp rename to dynamic_programming/subset_sum_dynamic.cpp diff --git a/dynamic_programming/unbounded_0_1_knapsack.cpp b/dynamic_programming/unbounded_0_1_knapsack.cpp index 96588fe3936..384ea997884 100644 --- a/dynamic_programming/unbounded_0_1_knapsack.cpp +++ b/dynamic_programming/unbounded_0_1_knapsack.cpp @@ -1,33 +1,33 @@ /** * @file * @brief Implementation of the Unbounded 0/1 Knapsack Problem - * - * @details - * The Unbounded 0/1 Knapsack problem allows taking unlimited quantities of each item. - * The goal is to maximize the total value without exceeding the given knapsack capacity. - * Unlike the 0/1 knapsack, where each item can be taken only once, in this variation, - * any item can be picked any number of times as long as the total weight stays within - * the knapsack's capacity. - * - * Given a set of N items, each with a weight and a value, represented by the arrays - * `wt` and `val` respectively, and a knapsack with a weight limit W, the task is to - * fill the knapsack to maximize the total value. * - * @note weight and value of items is greater than zero + * @details + * The Unbounded 0/1 Knapsack problem allows taking unlimited quantities of each + * item. The goal is to maximize the total value without exceeding the given + * knapsack capacity. Unlike the 0/1 knapsack, where each item can be taken only + * once, in this variation, any item can be picked any number of times as long + * as the total weight stays within the knapsack's capacity. + * + * Given a set of N items, each with a weight and a value, represented by the + * arrays `wt` and `val` respectively, and a knapsack with a weight limit W, the + * task is to fill the knapsack to maximize the total value. + * + * @note weight and value of items is greater than zero * * ### Algorithm - * The approach uses dynamic programming to build a solution iteratively. - * A 2D array is used for memoization to store intermediate results, allowing + * The approach uses dynamic programming to build a solution iteratively. + * A 2D array is used for memoization to store intermediate results, allowing * the function to avoid redundant calculations. - * + * * @author [Sanskruti Yeole](https://github.com/yeolesanskruti) * @see dynamic_programming/0_1_knapsack.cpp */ +#include // For using assert function to validate test cases +#include // For fixed-width integer types like std::uint16_t #include // Standard input-output stream -#include // Standard library for using dynamic arrays (vectors) -#include // For using assert function to validate test cases -#include // For fixed-width integer types like std::uint16_t +#include // Standard library for using dynamic arrays (vectors) /** * @namespace dynamic_programming @@ -42,7 +42,7 @@ namespace dynamic_programming { namespace unbounded_knapsack { /** - * @brief Recursive function to calculate the maximum value obtainable using + * @brief Recursive function to calculate the maximum value obtainable using * an unbounded knapsack approach. * * @param i Current index in the value and weight vectors. @@ -52,27 +52,33 @@ namespace unbounded_knapsack { * @param wt Vector of weights corresponding to the items. * @note "wt" data type can be changed according to the size of the input. * @param dp 2D vector for memoization to avoid redundant calculations. - * @return The maximum value that can be obtained for the given index and capacity. + * @return The maximum value that can be obtained for the given index and + * capacity. */ -std::uint16_t KnapSackFilling(std::uint16_t i, std::uint16_t W, - const std::vector& val, - const std::vector& wt, - std::vector>& dp) { +std::uint16_t KnapSackFilling(std::uint16_t i, std::uint16_t W, + const std::vector& val, + const std::vector& wt, + std::vector>& dp) { if (i == 0) { if (wt[0] <= W) { - return (W / wt[0]) * val[0]; // Take as many of the first item as possible + return (W / wt[0]) * + val[0]; // Take as many of the first item as possible } else { - return 0; // Can't take the first item + return 0; // Can't take the first item } } - if (dp[i][W] != -1) return dp[i][W]; // Return result if available + if (dp[i][W] != -1) + return dp[i][W]; // Return result if available - int nottake = KnapSackFilling(i - 1, W, val, wt, dp); // Value without taking item i + int nottake = + KnapSackFilling(i - 1, W, val, wt, dp); // Value without taking item i int take = 0; if (W >= wt[i]) { - take = val[i] + KnapSackFilling(i, W - wt[i], val, wt, dp); // Value taking item i + take = val[i] + KnapSackFilling(i, W - wt[i], val, wt, + dp); // Value taking item i } - return dp[i][W] = std::max(take, nottake); // Store and return the maximum value + return dp[i][W] = + std::max(take, nottake); // Store and return the maximum value } /** @@ -84,17 +90,19 @@ std::uint16_t KnapSackFilling(std::uint16_t i, std::uint16_t W, * @param wt Vector of weights corresponding to the items. * @return The maximum value that can be obtained for the given capacity. */ -std::uint16_t unboundedKnapsack(std::uint16_t N, std::uint16_t W, - const std::vector& val, - const std::vector& wt) { - if(N==0)return 0; // Expect 0 since no items - std::vector> dp(N, std::vector(W + 1, -1)); // Initialize memoization table - return KnapSackFilling(N - 1, W, val, wt, dp); // Start the calculation +std::uint16_t unboundedKnapsack(std::uint16_t N, std::uint16_t W, + const std::vector& val, + const std::vector& wt) { + if (N == 0) + return 0; // Expect 0 since no items + std::vector> dp( + N, std::vector(W + 1, -1)); // Initialize memoization table + return KnapSackFilling(N - 1, W, val, wt, dp); // Start the calculation } -} // unbounded_knapsack +} // namespace unbounded_knapsack -} // dynamic_programming +} // namespace dynamic_programming /** * @brief self test implementation @@ -102,42 +110,57 @@ std::uint16_t unboundedKnapsack(std::uint16_t N, std::uint16_t W, */ static void tests() { // Test Case 1 - std::uint16_t N1 = 4; // Number of items - std::vector wt1 = {1, 3, 4, 5}; // Weights of the items - std::vector val1 = {6, 1, 7, 7}; // Values of the items - std::uint16_t W1 = 8; // Maximum capacity of the knapsack + std::uint16_t N1 = 4; // Number of items + std::vector wt1 = {1, 3, 4, 5}; // Weights of the items + std::vector val1 = {6, 1, 7, 7}; // Values of the items + std::uint16_t W1 = 8; // Maximum capacity of the knapsack // Test the function and assert the expected output - assert(unboundedKnapsack(N1, W1, val1, wt1) == 48); - std::cout << "Maximum Knapsack value " << unboundedKnapsack(N1, W1, val1, wt1) << std::endl; + assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N1, W1, val1, wt1) == 48); + std::cout << "Maximum Knapsack value " + << dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N1, W1, val1, wt1) + << std::endl; // Test Case 2 - std::uint16_t N2 = 3; // Number of items - std::vector wt2 = {10, 20, 30}; // Weights of the items - std::vector val2 = {60, 100, 120}; // Values of the items - std::uint16_t W2 = 5; // Maximum capacity of the knapsack + std::uint16_t N2 = 3; // Number of items + std::vector wt2 = {10, 20, 30}; // Weights of the items + std::vector val2 = {60, 100, 120}; // Values of the items + std::uint16_t W2 = 5; // Maximum capacity of the knapsack // Test the function and assert the expected output - assert(unboundedKnapsack(N2, W2, val2, wt2) == 0); - std::cout << "Maximum Knapsack value " << unboundedKnapsack(N2, W2, val2, wt2) << std::endl; + assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N2, W2, val2, wt2) == 0); + std::cout << "Maximum Knapsack value " + << dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N2, W2, val2, wt2) + << std::endl; // Test Case 3 - std::uint16_t N3 = 3; // Number of items - std::vector wt3 = {2, 4, 6}; // Weights of the items - std::vector val3 = {5, 11, 13};// Values of the items - std::uint16_t W3 = 27;// Maximum capacity of the knapsack + std::uint16_t N3 = 3; // Number of items + std::vector wt3 = {2, 4, 6}; // Weights of the items + std::vector val3 = {5, 11, 13}; // Values of the items + std::uint16_t W3 = 27; // Maximum capacity of the knapsack // Test the function and assert the expected output - assert(unboundedKnapsack(N3, W3, val3, wt3) == 27); - std::cout << "Maximum Knapsack value " << unboundedKnapsack(N3, W3, val3, wt3) << std::endl; + assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N3, W3, val3, wt3) == 27); + std::cout << "Maximum Knapsack value " + << dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N3, W3, val3, wt3) + << std::endl; // Test Case 4 - std::uint16_t N4 = 0; // Number of items - std::vector wt4 = {}; // Weights of the items - std::vector val4 = {}; // Values of the items - std::uint16_t W4 = 10; // Maximum capacity of the knapsack - assert(unboundedKnapsack(N4, W4, val4, wt4) == 0); - std::cout << "Maximum Knapsack value for empty arrays: " << unboundedKnapsack(N4, W4, val4, wt4) << std::endl; - - std::cout << "All test cases passed!" << std::endl; + std::uint16_t N4 = 0; // Number of items + std::vector wt4 = {}; // Weights of the items + std::vector val4 = {}; // Values of the items + std::uint16_t W4 = 10; // Maximum capacity of the knapsack + assert(dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N4, W4, val4, wt4) == 0); + std::cout << "Maximum Knapsack value for empty arrays: " + << dynamic_programming::unbounded_knapsack::unboundedKnapsack( + N4, W4, val4, wt4) + << std::endl; + std::cout << "All test cases passed!" << std::endl; } /** @@ -145,7 +168,6 @@ static void tests() { * @return 0 on successful exit */ int main() { - tests(); // Run self test implementation + tests(); // Run self test implementation return 0; } - diff --git a/dynamic_programming/word_break.cpp b/dynamic_programming/word_break.cpp index 5291f665f59..2ec355a4b5f 100644 --- a/dynamic_programming/word_break.cpp +++ b/dynamic_programming/word_break.cpp @@ -105,7 +105,7 @@ bool check(const std::string &s, const std::unordered_set &strSet, // if the prefix till current position is present in the dictionary // and the remaining substring can also be segmented legally, then // set solution at position pos in the memo, and return true - if (exists(wordTillNow, strSet) and check(s, strSet, i + 1, dp)) { + if (exists(wordTillNow, strSet) && check(s, strSet, i + 1, dp)) { dp->at(pos) = 1; return true; } diff --git a/greedy_algorithms/CMakeLists.txt b/greedy_algorithms/CMakeLists.txt new file mode 100644 index 00000000000..bd45da6d4e9 --- /dev/null +++ b/greedy_algorithms/CMakeLists.txt @@ -0,0 +1,18 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + if(OpenMP_CXX_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_CXX) + endif() + install(TARGETS ${testname} DESTINATION "bin/greedy_algorithms") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/greedy_algorithms/dijkstra.cpp b/greedy_algorithms/dijkstra_greedy.cpp similarity index 100% rename from greedy_algorithms/dijkstra.cpp rename to greedy_algorithms/dijkstra_greedy.cpp diff --git a/greedy_algorithms/knapsack.cpp b/greedy_algorithms/knapsack.cpp index 74be4fee0e0..b5e9f6374ec 100644 --- a/greedy_algorithms/knapsack.cpp +++ b/greedy_algorithms/knapsack.cpp @@ -44,7 +44,7 @@ int main() { cout << "\n Enter the number of Items : "; int n; cin >> n; - Item itemArray[n]; + Item *itemArray = new Item[n]; for (int i = 0; i < n; i++) { cout << "\nEnter the weight and profit of item " << i + 1 << " : "; cin >> itemArray[i].weight; @@ -73,6 +73,6 @@ int main() { } cout << "\nMax Profit : " << maxProfit; - + delete[] itemArray; return 0; } diff --git a/operations_on_datastructures/CMakeLists.txt b/operations_on_datastructures/CMakeLists.txt new file mode 100644 index 00000000000..09119bc4300 --- /dev/null +++ b/operations_on_datastructures/CMakeLists.txt @@ -0,0 +1,15 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + install(TARGETS ${testname} DESTINATION "bin/operations_on_datastructures") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/operations_on_datastructures/circular_queue_using_array.cpp b/operations_on_datastructures/circular_queue_using_array.cpp index e0e049611da..58abbd7b649 100644 --- a/operations_on_datastructures/circular_queue_using_array.cpp +++ b/operations_on_datastructures/circular_queue_using_array.cpp @@ -1,5 +1,6 @@ #include -using namespace std; +using std::cin; +using std::cout; int queue[10]; int front = 0; diff --git a/operations_on_datastructures/trie_multiple_search.cpp b/operations_on_datastructures/trie_multiple_search.cpp index 854354fdfff..6dbb9d338d6 100644 --- a/operations_on_datastructures/trie_multiple_search.cpp +++ b/operations_on_datastructures/trie_multiple_search.cpp @@ -1,6 +1,7 @@ /** * @file - * @brief [Trie datastructure](https://iq.opengenus.org/autocomplete-using-trie-data-structure/) + * @brief [Trie + * datastructure](https://iq.opengenus.org/autocomplete-using-trie-data-structure/) * with search variants * @details * This provides multiple variants of search functions @@ -12,6 +13,7 @@ #include /// for std::count #include /// for assert #include /// for tolower +#include /// for std::uint32_t #include /// for string operations #include /// for IO Operations #include /// for std::priority_queue @@ -23,7 +25,8 @@ namespace operations_on_datastructures { /** * @namespace trie_operations - * @brief Functions for [Trie datastructure](https://iq.opengenus.org/autocomplete-using-trie-data-structure/) + * @brief Functions for [Trie + * datastructure](https://iq.opengenus.org/autocomplete-using-trie-data-structure/) * implementation */ namespace trie_operations { diff --git a/others/fast_integer_input.cpp b/others/fast_integer_input.cpp index 87963c9ad88..c929305c75b 100644 --- a/others/fast_integer_input.cpp +++ b/others/fast_integer_input.cpp @@ -11,7 +11,7 @@ void fastinput(int *number) { // variable to indicate sign of input integer bool negative = false; - register int c; + int c; *number = 0; // extract current character from buffer diff --git a/range_queries/CMakeLists.txt b/range_queries/CMakeLists.txt new file mode 100644 index 00000000000..c9f0c86f0a8 --- /dev/null +++ b/range_queries/CMakeLists.txt @@ -0,0 +1,18 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + if(OpenMP_CXX_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_CXX) + endif() + install(TARGETS ${testname} DESTINATION "bin/range_queries") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/range_queries/mo.cpp b/range_queries/mo.cpp index d281ef077ee..10abf0a96c3 100644 --- a/range_queries/mo.cpp +++ b/range_queries/mo.cpp @@ -1,4 +1,7 @@ +#include +#include #include + using namespace std; const int N = 1e6 + 5; int a[N], bucket[N], cnt[N]; diff --git a/range_queries/segtree.cpp b/range_queries/segtree.cpp index 71e6890fb1f..785d5325f8e 100644 --- a/range_queries/segtree.cpp +++ b/range_queries/segtree.cpp @@ -21,6 +21,7 @@ #include /// for assert #include /// for log2 +#include /// for std::uint64_t #include /// for IO operations #include /// for std::vector diff --git a/range_queries/sparse_table.cpp b/range_queries/sparse_table_range_queries.cpp similarity index 100% rename from range_queries/sparse_table.cpp rename to range_queries/sparse_table_range_queries.cpp