Merge pull request #2 from TheAlgorithms/master

update fork TheAlgorithms/C-Plus-Plus
This commit is contained in:
Ayaan Khan
2020-06-13 04:19:51 +05:30
committed by GitHub
4 changed files with 344 additions and 1 deletions

View File

@@ -49,6 +49,7 @@
* [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/stack.h)
* [Test Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/stk/test_stack.cpp)
* [Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/Tree.cpp)
* [Trie Modern](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/trie_modern.cpp)
* [Trie Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structure/trie_tree.cpp)
## Dynamic Programming
@@ -72,6 +73,9 @@
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/tree_height.cpp)
## Geometry
* [Line Segment Intersection](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/line_segment_intersection.cpp)
## Graph
* [Bfs](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/BFS.cpp)
* [Bridge Finding With Tarjan Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/bridge_finding_with_tarjan_algorithm.cpp)
@@ -111,6 +115,7 @@
* [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp)
* [Greatest Common Divisor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor.cpp)
* [Greatest Common Divisor Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor_euclidean.cpp)
* [Least Common Multiple](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/least_common_multiple.cpp)
* [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp)
* [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp)
* [Power For Huge Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/power_for_huge_numbers.cpp)
@@ -196,7 +201,7 @@
* [Non Recursive Merge Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/non_recursive_merge_sort.cpp)
* [Numericstringsort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/NumericStringSort.cpp)
* [Oddeven Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/OddEven%20Sort.cpp)
* [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Quick%20Sort.cpp)
* [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/quick_sort.cpp)
* [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Radix%20Sort.cpp)
* [Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Selection%20Sort.cpp)
* [Shell Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/Shell%20Sort.cpp)

View File

@@ -0,0 +1,167 @@
/**
* Copyright 2020 @author Anmol3299
* @file
*
* A basic implementation of trie class to store only lower-case strings.
*/
#include <iostream> // for io operations
#include <memory> // for std::shared_ptr<>
#include <string> // for std::string class
/**
* A basic implementation of trie class to store only lower-case strings.
* You can extend the implementation to all the ASCII characters by changing the
* value of @ ALPHABETS to 128.
*/
class Trie {
private:
static constexpr size_t ALPHABETS = 26;
/**
* Structure of trie node.
* This struct doesn't need a constructor as we are initializing using
* intializer list which is more efficient than if we had done so with
* constructor.
*/
struct TrieNode {
// An array of pointers of size 26 which tells if a character of word is
// present or not.
std::shared_ptr<TrieNode> character[ALPHABETS]{nullptr};
bool isEndOfWord{false};
};
/**
* Function to check if a node has some children which can form words.
* @param node whose character array of pointers need to be checked for
* children.
* @return if a child is found, it returns @ true, else it returns @ false.
*/
inline static bool hasChildren(std::shared_ptr<TrieNode> node) {
for (size_t i = 0; i < ALPHABETS; i++) {
if (node->character[i]) {
return true;
}
}
return false;
}
/**
* A recursive helper function to remove a word from the trie. First, it
* recursively traverses to the location of last character of word in the
* trie. However, if the word is not found, the function returns a runtime
* error. Upon successfully reaching the last character of word in trie, if
* sets the isEndOfWord to false and deletes the node if and only if it has
* no children, else it returns the current node.
* @param word is the string which needs to be removed from trie.
* @param curr is the current node we are at.
* @param index is the index of the @word we are at.
* @return if current node has childern, it returns @ curr, else it returns
* nullptr.
* @throw a runtime error in case @ word is not found in the trie.
*/
std::shared_ptr<TrieNode> removeWordHelper(const std::string& word,
std::shared_ptr<TrieNode> curr,
size_t index) {
if (word.size() == index) {
if (curr->isEndOfWord) {
curr->isEndOfWord = false;
}
if (hasChildren(curr)) {
return curr;
}
return nullptr;
}
size_t idx = word[index] - 'a';
// Throw a runtime error in case the user enters a word which is not
// present in the trie.
if (!curr->character[idx]) {
throw std::runtime_error(std::move(std::string("Word not found.")));
}
curr->character[idx] =
removeWordHelper(word, curr->character[idx], index + 1);
// This if condition checks if the node has some childern.
// The 1st if check, i.e. (curr->character[idx]) is checked specifically
// because if the older string is a prefix of some other string, then,
// there would be no need to check all 26 characters. Example- str1 =
// abbey, str2 = abbex and we want to delete string "abbey", then in
// this case, there would be no need to check all characters for the
// chars a,b,b.
if (curr->character[idx] || hasChildren(curr)) {
return curr;
}
return nullptr;
}
public:
// constructor to initialise the root of the trie.
Trie() : m_root(std::make_shared<TrieNode>()) {}
/**
* Insert a word into the trie.
* @param word which needs to be inserted into the string.
*/
void insert(const std::string& word) {
auto curr = m_root;
for (char ch : word) {
size_t index = ch - 'a';
// if a node for current word is not already present in trie, create
// a new node for it.
if (!curr->character[index]) {
curr->character[index] = std::make_shared<TrieNode>();
}
curr = curr->character[index];
}
curr->isEndOfWord = true;
}
/**
* Search if a word is present in trie or not.
* @param word which is needed to be searched in the trie.
* @return True if the word is found in trie and isEndOfWord is set to true.
* @return False if word is not found in trie or isEndOfWord is set to
* false.
*/
bool search(const std::string& word) {
auto curr = m_root;
for (char ch : word) {
size_t index = ch - 'a';
// if any node for a character is not found, then return that the
// word cannot be formed.
if (!curr->character[index]) {
return false;
}
curr = curr->character[index];
}
return curr->isEndOfWord;
}
// Function to remove the word which calls the helper function.
void removeWord(const std::string& word) {
m_root = removeWordHelper(word, m_root, 0);
}
private:
// data member to store the root of the trie.
std::shared_ptr<TrieNode> m_root;
};
/**
* Main function
*/
int main() {
Trie trie;
trie.insert("hel");
trie.insert("hello");
trie.removeWord("hel");
std::cout << trie.search("hello") << '\n';
return 0;
}

View File

@@ -0,0 +1,101 @@
/**
* @file
* @brief check whether two line segments intersect each other
* or not.
*/
#include <iostream>
/**
* Define a Point.
*/
struct Point {
int x; /// Point respect to x coordinate
int y; /// Point respect to y coordinate
};
/**
* intersect returns true if segments of two line intersects and
* false if they do not. It calls the subroutines direction
* which computes the orientation.
*/
struct SegmentIntersection {
inline bool intersect(Point first_point, Point second_point,
Point third_point, Point forth_point) {
int direction1 = direction(third_point, forth_point, first_point);
int direction2 = direction(third_point, forth_point, second_point);
int direction3 = direction(first_point, second_point, third_point);
int direction4 = direction(first_point, second_point, forth_point);
if ((direction1 < 0 || direction2 > 0) && (direction3 < 0 ||
direction4 > 0))
return true;
else if (direction1 == 0 && on_segment(third_point, forth_point,
first_point))
return true;
else if (direction2 == 0 && on_segment(third_point, forth_point,
second_point))
return true;
else if (direction3 == 0 && on_segment(first_point, second_point,
third_point))
return true;
else if (direction3 == 0 && on_segment(first_point, second_point,
forth_point))
return true;
else
return false;
}
/**
* We will find direction of line here respect to @first_point.
* Here @second_point and @third_point is first and second points
* of the line respectively. we want a method to determine which way a
* given angle these three points turns. If returned number is negative,
* then the angle is counter-clockwise. That means the line is going to
* right to left. We will fount angle as clockwise if the method returns
* positive number.
*/
inline int direction(Point first_point, Point second_point,
Point third_point) {
return ((third_point.x-first_point.x)*(second_point.y-first_point.y))-
((second_point.x-first_point.x) * (third_point.y-first_point.y));
}
/**
* This method determines whether a point known to be colinear
* with a segment lies on that segment.
*/
inline bool on_segment(Point first_point, Point second_point,
Point third_point) {
if (std::min(first_point.x, second_point.x) <= third_point.x &&
third_point.x <= std::max(first_point.x, second_point.x) &&
std::min(first_point.y, second_point.y) <= third_point.y &&
third_point.y <= std::max(first_point.y, second_point.y))
return true;
else
return false;
}
};
/**
* This is the main function to test whether the algorithm is
* working well.
*/
int main() {
SegmentIntersection segment;
Point first_point, second_point, third_point, forth_point;
std::cin >> first_point.x >> first_point.y;
std::cin >> second_point.x >> second_point.y;
std::cin >> third_point.x >> third_point.y;
std::cin >> forth_point.x >> forth_point.y;
printf("%d", segment.intersect(first_point, second_point, third_point,
forth_point));
std::cout << std::endl;
}

View File

@@ -0,0 +1,70 @@
/**
* Copyright 2020 @author tjgurwara99
* @file
*
* A basic implementation of LCM function
*/
#include <cassert>
#include <iostream>
/**
* Function for finding greatest common divisor of two numbers.
* @params two integers x and y whose gcd we want to find.
* @return greatest common divisor of x and y.
*/
unsigned int gcd(unsigned int x, unsigned int y) {
if (x == 0) {
return y;
}
if (y == 0) {
return x;
}
if (x == y) {
return x;
}
if (x > y) {
// The following is valid because we have checked whether y == 0
int temp = x / y;
return gcd(y, x - temp * y);
}
// Again the following is valid because we have checked whether x == 0
int temp = y / x;
return gcd(x, y - temp * x);
}
/**
* Function for finding the least common multiple of two numbers.
* @params integer x and y whose lcm we want to find.
* @return lcm of x and y using the relation x * y = gcd(x, y) * lcm(x, y)
*/
unsigned int lcm(unsigned int x, unsigned int y) { return x * y / gcd(x, y); }
/**
* Function for testing the lcm() functions with some assert statements.
*/
void tests() {
// First test on lcm(5,10) == 10
assert(((void)"LCM of 5 and 10 is 10 but lcm function gives a different "
"result.\n",
lcm(5, 10) == 10));
std::cout << "First assertion passes: LCM of 5 and 10 is " << lcm(5, 10)
<< std::endl;
// Second test on lcm(2,3) == 6 as 2 and 3 are coprime (prime in fact)
assert(((void)"LCM of 2 and 3 is 6 but lcm function gives a different "
"result.\n",
lcm(2, 3) == 6));
std::cout << "Second assertion passes: LCM of 2 and 3 is " << lcm(2, 3)
<< std::endl;
}
/**
* Main function
*/
int main() {
tests();
return 0;
}