-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added chapters 04,05,06 and latest exercises (#7)
- Loading branch information
1 parent
2d9c436
commit be73f8c
Showing
43 changed files
with
1,573 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/c04) | ||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
td_add_all_subdirectories() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Search | ||
|
||
Contains implementations for search algorithms. | ||
|
||
## Fields / Arrays / Queues / Stacks | ||
|
||
- [searcharray](searcharray) | ||
C++ implementation of several search algorithms in a Template. | ||
|
||
<!-- | ||
- [array](array) | ||
Utilizes the [array](../02_datastructures/array) to illustrate certain search algorithms implemented in C. | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
add_library(searcharray searcharray.cpp searcharray.h) | ||
set_target_properties(searcharray PROPERTIES PUBLIC_HEADER "searcharray.h") | ||
install(TARGETS searcharray PUBLIC_HEADER DESTINATION include/searcharray) | ||
|
||
add_executable(searcharray_test searcharray_test.cpp) | ||
target_link_libraries(searcharray_test searcharray) | ||
install(TARGETS searcharray_test DESTINATION bin/c04) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* When working with templates, the function definition (body) | ||
* must be implemented in the header file. | ||
* Implementation here works with GCC, but not with CLang. | ||
*/ | ||
#include "searcharray.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
#ifndef SEARCHARRAY_H | ||
#define SEARCHARRAY_H | ||
|
||
#include <iostream> | ||
|
||
#include "dynarray/dynarray.h" | ||
|
||
namespace fom | ||
{ | ||
namespace AuD | ||
{ | ||
/** | ||
* Templated Array implementation in C++ for illustrating search functions. | ||
*/ | ||
template <typename T> | ||
class SearchArray : public Array<T> | ||
{ | ||
|
||
public: | ||
/** Default constructor. */ | ||
SearchArray(); | ||
/** Destructor, free's resources. */ | ||
virtual ~SearchArray(); | ||
|
||
/** | ||
* "Sequential" search, searching the Array "from left to right". | ||
* @return position of the found element. -1 if not found. | ||
*/ | ||
int search_sequential(const T &val) const; | ||
|
||
/** | ||
* "Binary" search algorithms. | ||
* Internally calls search_binary_rec() recursively. | ||
* @return position of the found element. -1 if not found. | ||
*/ | ||
int search_binary(const T &val) const; | ||
|
||
/** | ||
* Interpolation search. | ||
* Internally calls search_interpolation_rec() recursively | ||
* @return position of the found element. -1 if not found. | ||
*/ | ||
int search_interpolation(const T &val) const; | ||
|
||
/** | ||
* Exponential search. | ||
* @return position of the found element. -1 if not found. | ||
*/ | ||
int search_exponential(const T &val) const; | ||
|
||
protected: | ||
/** | ||
* Recursive implementation of the binary search algorithms. | ||
* @param steps just a counter for keeping track of the steps. | ||
* @param val the value to be searched for. | ||
* @param left the "lower" limit in the binary search algorithm. | ||
* @param right the "upper" limit in the binary search algorithm. | ||
*/ | ||
int search_binary_rec(std::size_t& steps, const T &val, std::size_t left, std::size_t right) const; | ||
|
||
/** | ||
* Recursive implementation of the interpolation search algorithms. | ||
* | ||
* \f[ | ||
* i = l + \frac{r-l}{a[r]-a[l]}\cdot\left( x-a[l] \right) | ||
* \f] | ||
* where \f$ x \f$ the value we're looking for, \f$ i \f$ is the next "probing" position, | ||
* \f$ a \f$ this array, \f$ l \f$ the left boundary and \f$ r \f$ the right boundary. | ||
* @param steps just a counter for keeping track of the steps. | ||
* @param val the value to be searched for. | ||
* @param left the "lower" limit in the search algorithm. | ||
* @param right the "upper" limit in the search algorithm. | ||
*/ | ||
int search_interpolation_rec(std::size_t& steps, const T &val, std::size_t left, std::size_t right) const; | ||
}; | ||
} | ||
} | ||
|
||
/** | ||
* Output function for fom::AuD::SearchArray<T>. | ||
* Needs to be defined in header, see https://stackoverflow.com/questions/8752837/undefined-reference-to-template-class-constructor . | ||
*/ | ||
template <typename T> | ||
std::ostream &operator<<(std::ostream &os, const fom::AuD::SearchArray<T> &o) | ||
{ | ||
os << o.toString(); | ||
return os; | ||
} | ||
|
||
namespace fom | ||
{ | ||
namespace AuD | ||
{ | ||
|
||
template <typename T> | ||
SearchArray<T>::SearchArray() : Array<T>() | ||
{ | ||
} | ||
|
||
template <typename T> | ||
SearchArray<T>::~SearchArray() | ||
{ | ||
// superclass destructor called automatically! | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_sequential(const T &val) const | ||
{ | ||
std::size_t idx = 0; | ||
for (typename Array<T>::const_iterator cItr = this->begin(); cItr != this->end(); ++cItr) | ||
{ | ||
this->callback({idx}); | ||
if (*cItr == val) | ||
{ | ||
return idx; | ||
} | ||
++idx; | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_binary(const T &val) const | ||
{ | ||
this->callback({0, this->size() - 1}); | ||
std::size_t steps = 0; | ||
int returnVal = search_binary_rec(steps, val, 0, this->size() - 1); | ||
|
||
return returnVal; | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_binary_rec(std::size_t& steps, const T &val, std::size_t left, std::size_t right) const | ||
{ | ||
steps++; | ||
if (right >= left) | ||
{ | ||
std::cout << " Step " << steps << std::endl; | ||
std::size_t mid = left + (right - left) / 2; | ||
this->callback({mid, left, right}); | ||
|
||
// element is at the middle | ||
if (this->at(mid) == val) | ||
return mid; | ||
|
||
// element < mid, then consider "left" subarray [with mid-1 as right border] | ||
if (this->at(mid) > val) | ||
return search_binary_rec(steps, val, left, mid - 1); | ||
|
||
// element > mid, then consider "right" subarray [with mid+1 as left border] | ||
return search_binary_rec(steps, val, mid + 1, right); | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_interpolation(const T &val) const | ||
{ | ||
this->callback({0, this->size() - 1}); | ||
std::size_t steps = 0; | ||
return search_interpolation_rec(steps, val, 0, this->size() - 1); | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_interpolation_rec(std::size_t& steps, const T &val, std::size_t left, std::size_t right) const | ||
{ | ||
std::size_t pos; | ||
steps++; | ||
|
||
// Value must be found in boundaries > left && < right | ||
if (left <= right && (val >= this->at(left) && val <= this->at(right))) | ||
{ | ||
std::cout << " Step " << steps << std::endl; | ||
|
||
// Probing - see formula in function description | ||
pos = left + (((double)(right - left) / (this->at(right) - this->at(left))) * (val - this->at(left))); | ||
this->callback({pos, left, right}); | ||
|
||
// Found? | ||
if (this->at(pos) == val) | ||
return pos; | ||
|
||
// val is larger => val in right sub array | ||
if (this->at(pos) < val) | ||
return search_interpolation_rec(steps, val, pos + 1, right); | ||
|
||
// val is smaller => val in left sub array | ||
if (this->at(pos) > val) | ||
return search_interpolation_rec(steps, val, left, pos - 1); | ||
} | ||
return -1; | ||
} | ||
|
||
template <typename T> | ||
int SearchArray<T>::search_exponential(const T &val) const | ||
{ | ||
size_t n = this->size(); | ||
// found at first position? | ||
if (this->at(0) == val) | ||
return 0; | ||
|
||
// Determine range of binary search | ||
// Repeat doubling interval and check if searched value in it. | ||
std::size_t i = 1; | ||
while (i < n && this->at(i) <= val) | ||
{ | ||
i = i * 2; | ||
this->callback({i, i / 2}); | ||
} | ||
|
||
// binary search for the found range. | ||
std::size_t steps; | ||
return this->search_binary_rec(steps, val, i / 2, std::min(i, n - 1)); | ||
} | ||
} | ||
} | ||
|
||
#endif // SEARCHARRAY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include <iostream> | ||
#include <string> | ||
|
||
#include "searcharray.h" | ||
|
||
int main() | ||
{ | ||
typedef fom::AuD::SearchArray<int> SearchArray; | ||
|
||
std::cout << "#---- Some search tests on SearchArray" << std::endl; | ||
{ | ||
SearchArray array; | ||
|
||
array.push_back(10); | ||
array.push_back(15); | ||
array.push_back(1); | ||
array.push_back(3); | ||
array.push_back(5); | ||
array.push_back(7); | ||
array.push_back(9); | ||
array.push_back(25); | ||
array.push_back(13); | ||
array.push_back(9); | ||
array.push_back(45); | ||
array.push_back(46); | ||
array.push_back(33); | ||
array.push_back(42); | ||
|
||
std::cout << array.toString() << std::endl; | ||
|
||
std::cout << "Random access of some elements: " << std::endl; | ||
std::cout << " [0] - " << array[0] << std::endl; | ||
std::cout << " [3] - " << array[2] << std::endl; | ||
|
||
std::cout << "Test some other functions: " << std::endl; | ||
std::cout << " Size: " << array.size() << std::endl; | ||
|
||
std::cout << "#---- Sorting array (no particular algorithm)." << std::endl; | ||
array.sort_simple(); | ||
std::cout << array.toString() << std::endl; | ||
|
||
std::cout << "#---- Searching Sequential." << std::endl; | ||
std::cout << " Pos of 33: " << std::endl << array.search_sequential(33) << std::endl; | ||
|
||
std::cout << "#---- Searching Binary." << std::endl; | ||
std::cout << " Pos of 33: " << std::endl << array.search_binary(33) << std::endl; | ||
|
||
std::cout << "#---- Searching Interpolation." << std::endl; | ||
std::cout << " Pos of 33: " << std::endl << array.search_interpolation(33) << std::endl; | ||
|
||
std::cout << "#---- Searching Exponential." << std::endl; | ||
std::cout << " Pos of 33: " << std::endl << array.search_exponential(33) << std::endl; | ||
} | ||
|
||
std::cout << "#---- Excercise from slides" << std::endl; | ||
{ | ||
SearchArray array; | ||
|
||
array.fromVector({10, 14, 33, 41, 45, 59, 73, 82, 90, 101, 118, 119, 134, 141, 150}); | ||
std::cout << " Searching Binary." << std::endl; | ||
std::cout << " Pos of 45: " << std::endl << array.search_binary(45) << std::endl; | ||
|
||
std::cout << " Comparing interpolation search in two lists." << std::endl; | ||
|
||
std::cout << " Searching Interpolation." << std::endl; | ||
std::cout << " Pos of 45: " << std::endl << array.search_interpolation(45) << std::endl; | ||
|
||
std::cout << " Loading second array." << std::endl; | ||
array.fromVector({10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 45, 150}); | ||
std::cout << " Searching Interpolation." << std::endl; | ||
std::cout << " Pos of 45: " << std::endl << array.search_interpolation(45) << std::endl; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
add_library(fomstring fomstring.cpp fomstring.h) | ||
set_target_properties(fomstring PROPERTIES PUBLIC_HEADER "fomstring.h") | ||
install(TARGETS fomstring PUBLIC_HEADER DESTINATION include/stringsearch) | ||
|
||
add_executable(stringsearch_test stringsearch_test.cpp) | ||
target_link_libraries(stringsearch_test fomstring) | ||
install(TARGETS stringsearch_test DESTINATION bin/c04) |
Oops, something went wrong.