Welcome to TheAlgorithms/C-Plus-Plus! Before submitting pull requests, please make sure that you have read the whole guidelines. If you have any doubts about this contribution guide, please open an issue or ask on our Discord server, and clearly state your concerns.
Please check the reviewer code file for maintainers and reviewers.
Being a contributor at The Algorithms, we request you to follow the points mentioned below:
New implementation New implementations are welcome!
You can add new algorithms or data structures that are not present in the repository or that can improve the old implementations (documentation, improving test cases, removing bugs, or in any other reasonable sense)
Issues Please avoid opening issues asking to be "assigned” to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request, and it will be evaluated by project maintainers.
*.hpp
, *.h
or *.cpp
.bits/stdc++.h
because this is quite Linux-specific and slows down the compilation process.struct
, class
, and/or namespace
keywords.README.md
along with other changes. First, create an issue and then link to that issue in your pull request to suggest specific changes required to README.md
.main()
function.test()
functions that will invoke the algorithm implementation on random test data with the expected output. Use the assert()
function to confirm that the tests will pass. Requires including the cassert
library.// Let's make sure the array of numbers is ordered after calling the function.
std::vector<uint64_t> arr = {5, 3, 8, 12, 14, 16, 28, 96, 2, 5977};
std::vector<uint64_t> arr_sorted = sorting::quick_sort::quick_sort(
arr, 0, int(std::end(arr) - std::begin(arr)) - 1);
assert(std::is_sorted(std::begin(arr_sorted), std::end(arr_sorted)));
std::vector<int32_t> array1 = {-7, -3, -2, 5, 8}; // input array
assert(backtracking::subset_sum::number_of_subsets(0, array1) ==
2); // first argument in subset_sum function is the required sum and
// second is the input array
#include <iostream> /// for IO operations
#include <vector> /// for std::vector
#include <cassert> /// for assert
/**
* @brief Verifies if the given array
* contains the given number on it.
* @tparam T the type of array (e.g., `int`, `float`, etc.)
* @param arr the array to be used for checking
* @param number the number to check if it's inside the array
* @return false if the number was NOT found in the array
* @return true if the number WAS found in the array
*/
template <typename T>
bool is_number_on_array(const std::vector<T> &arr, const int &number) {
for (int i = 0; i < sizeof(arr) / sizeof(int); i++) {
if (arr[i] == number) {
return true;
}
else {
// Number not in the current index, keep searching.
}
}
return false;
}
/**
* @brief Self-test implementations
* @returns void
*/
static void tests() {
std::vector<int> arr = { 9, 14, 21, 98, 67 };
assert(is_number_on_array(arr, 9) == true);
assert(is_number_on_array(arr, 4) == false);
assert(is_number_on_array(arr, 98) == true);
assert(is_number_on_array(arr, 512) == false);
std::cout << "All tests have successfully passed!\n";
}
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
tests(); // run self-test implementations
return 0;
}
/**
* @file
* @brief Add one-line description here. Should contain a Wikipedia
* link or another source explaining the algorithm/implementation.
* @details
* This is a multi-line
* description containing links, references,
* math equations, etc.
* @author [Name](https://github.com/handle)
* @see related_file.cpp, another_file.cpp
*/
#include <cassert> /// for assert
#include /// for `some function here`
/**
* @namespace
* @brief <namespace description>
*/
namespace name {
/**
* @brief Class documentation
*/
class class_name {
private:
int variable; ///< short info of this variable
char *message; ///< short info
public:
// other members should be also documented as below
}
/**
* @brief Function documentation
* @tparam T this is a one-line info about T
* @param param1 on-line info about param1
* @param param2 on-line info about param2
* @returns `true` if ...
* @returns `false` if ...
*/
template<class T>
bool func(int param1, T param2) {
// function statements here
if (/*something bad*/) {
return false;
}
return true;
}
} // namespace name
/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
/* descriptions of the following test */
assert(func(...) == ...); // this ensures that the algorithm works as expected
// can have multiple checks
// this lets the user know that the tests have passed
std::cout << "All tests have successfully passed!\n";
}
/**
* @brief Main function
* @param argc commandline argument count (ignored)
* @param argv commandline array of arguments (ignored)
* @returns 0 on exit
*/
int main(int argc, char *argv[]) {
test(); // run self-test implementations
// code here
return 0;
}
"_"
as a separatorMyNewCppClass.CPP is incorrect
my_new_cpp_class.cpp is correct format
median_search.cpp
already exists in the search
folder, and you are contributing a new implementation, the filename should be median_search2.cpp
. For a third implementation, median_search3.cpp
, and so on."_"
as separator ( no spaces or "-"
allowed )SomeNew Fancy-Category is incorrect
some_new_fancy_category is correct
In case a new directory is 100% required, CMakeLists.txt
file in the root directory needs to be updated, and a new CMakeLists.txt
file needs to be created within the new directory.
An example of how your new CMakeLists.txt
file should look like. Note that if there are any extra libraries/setup required, you must include that in this file as well.
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. The RELATIVE flag makes it easier to extract an executable's name
# automatically.
file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp )
foreach( testsourcefile ${APP_SOURCES} )
string( REPLACE ".cpp" "" testname ${testsourcefile} ) # File type. Example: `.cpp`
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/<foldername>") # Folder name. Do NOT include `<>`
endforeach( testsourcefile ${APP_SOURCES} )
The CMakeLists.txt
file in the root directory should be updated to include the new directory.\
Include your new directory after the last subdirectory. Example:
...
add_subdirectory(divide_and_conquer)
add_subdirectory(<foldername>)
git add file_xyz.cpp
git commit -m "your message"
Examples of commit messages with semantic prefixes:
fix: xyz algorithm bug
feat: add xyx algorithm, class xyz
test: add test for xyz algorithm
docs: add comments and explanation to xyz algorithm/improve contributing guidelines
chore: update Gitpod badge
Common prefixes:
Before submitting a pull request, build the code locally or using the convenient service.
cmake -B build -S .
We use clang-tidy
as a static code analyzer with a configuration in .clang-tidy
.
clang-tidy --fix --quiet -p build subfolder/file_to_check.cpp --
clang-format
is used for code formatting.
brew install clang-format
sudo port install clang-10 +analyzer
pacman -S mingw-w64-x86_64-clang-tools-extra
sudo apt-get install clang-format-10 clang-tidy-10
clang-format -i -style="file" my_file.cpp
clang-tidy
and clang-format
after every push (not a commit).
git pull
in your local clone if these actions made many changes to avoid merge conflicts.Most importantly,