加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Algorithm.h 21.55 KB
一键复制 编辑 原始数据 按行查看 历史
wenman-wsl 提交于 2023-10-03 22:24 . OK
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
#ifndef _ALGORITHM_H_
#define _ALGORITHM_H_
#include <cstring>
// #include <utility>
#include <iterator>
#include "Allocator.h"
#include "Functional.h"
#include "Iterator.h"
#include "TypeTraits.h"
#include "Utility.h"
namespace TinySTL{
//********* [fill] ********************
//********* [Algorithm Complexity: O(N)] ****************
template<class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value)
{
for (; first != last; ++first)
*first = value;
}
inline void fill(char *first, char *last, const char& value)
{
memset(first, static_cast<unsigned char>(value), last - first);
}
inline void fill(wchar_t *first, wchar_t *last, const wchar_t& value)
{
memset(first, static_cast<unsigned char>(value), (last - first) * sizeof(wchar_t));
}
//********* [fill_n] ********************
//********* [Algorithm Complexity: O(N)] ****************
template<class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value)
{
for (; n > 0; --n, ++first)
*first = value;
return first;
}
template<class Size>
char *fill_n(char *first, Size n, const char& value)
{
memset(first, static_cast<unsigned char>(value), n);
return first + n;
}
template<class Size>
wchar_t *fill_n(wchar_t *first, Size n, const wchar_t& value)
{
memset(first, static_cast<unsigned char>(value), n * sizeof(wchar_t));
return first + n;
}
//*********** [min] ********************
//********* [Algorithm Complexity: O(1)] ****************
template <class T>
const T& min(const T& a, const T& b){
return !(b < a) ? a : b;
}
template <class T, class Compare>
const T& min(const T& a, const T& b, Compare comp){
return !comp(b, a) ? a : b;
}
//*********** [max] ********************
//********* [Algorithm Complexity: O(1)] ****************
template <class T>
const T& max(const T& a, const T& b){
return (a < b) ? b : a;
}
template <class T, class Compare>
const T& max(const T& a, const T& b, Compare comp){
return (copm(a, b)) ? b : a;
}
//********** [make_heap] ***************
//********* [Algorithm Complexity: O(N)] ****************
template<class RandomAccessIterator, class Compare>
//heap上溯算法
static void up(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator head, Compare comp){//1.[first, last], 2.headr points the header of the heap
if (first != last){
int index = last - head;
auto parentIndex = (index - 1) / 2;
for (auto cur = last; parentIndex >= 0 && cur != head; parentIndex = (index - 1) / 2){
auto parent = head + parentIndex;//get parent
if (comp(*parent, *cur))
TinySTL::swap(*parent, *cur);
cur = parent;
index = cur - head;
}
}
}
template<class RandomAccessIterator, class Compare>
// heap下降算法
static void down(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator head, Compare comp){//1.[first, last], 2.headr points the header of the heap
if (first != last){
auto index = first - head;
auto leftChildIndex = index * 2 + 1;
for (auto cur = first; leftChildIndex < (last - head + 1) && cur < last; leftChildIndex = index * 2 + 1){
auto child = head + leftChildIndex;//get the left child
if ((child + 1) <= last && *(child + 1) > *child)//cur has a right child
child = child + 1;
if (comp(*cur, *child))
TinySTL::swap(*cur, *child);
cur = child;
index = cur - head;
}
}
}
template <class RandomAccessIterator, class Compare>
void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp){
const auto range = last - first;
for (auto cur = first + range / 2 - 1; cur >= first; --cur){
TinySTL::down(cur, last - 1, first, comp);
// if (cur == first) return;
}
}
template <class RandomAccessIterator>
void make_heap(RandomAccessIterator first, RandomAccessIterator last){
TinySTL::make_heap(first, last,
typename TinySTL::less<typename TinySTL::iterator_traits<RandomAccessIterator>::value_type>());
}
//********* [push_heap] ***************
//********* [Algorithm Complexity: O(lgN)] ****************
template <class RandomAccessIterator, class Compare>
void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp){
TinySTL::up(first, last - 1, first, comp);
}
template <class RandomAccessIterator>
void push_heap(RandomAccessIterator first, RandomAccessIterator last){
TinySTL::push_heap(first, last,
TinySTL::less<typename TinySTL::iterator_traits<RandomAccessIterator>::value_type>());
}
//********* [pop_heap] ***************
//********* [Algorithm Complexity: O(lgN)] ****************
template <class RandomAccessIterator, class Compare>
void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp){
TinySTL::swap(*first, *(last - 1));
if (last - first >= 2)
TinySTL::down(first, last - 2, first, comp);
}
template <class RandomAccessIterator>
void pop_heap(RandomAccessIterator first, RandomAccessIterator last){
TinySTL::pop_heap(first, last,
TinySTL::less<typename TinySTL::iterator_traits<RandomAccessIterator>::value_type>());
}
//********* [sort_heap] ***************
//********* [Algorithm Complexity: O(N)] ****************
template <class RandomAccessIterator, class Compare>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp){
for (auto cur = last; cur != first; --cur){
TinySTL::pop_heap(first, cur, comp);
}
}
template <class RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last){
return TinySTL::sort_heap(first, last,
TinySTL::less<typename TinySTL::iterator_traits<RandomAccessIterator>::value_type>());
}
//********* [is_heap] ***************
//********* [Algorithm Complexity: O(N)] ****************
template <class RandomAccessIterator, class Compare>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp){
const auto range = last - first;
auto index = range / 2 - 1;
for (auto cur = first + range / 2 - 1; cur >= first; --cur, --index){
if (*(first + (index * 2 + 1)) > *cur ||//left child > cur
((first + (index * 2 + 2)) <= last && *(first + (index * 2 + 2)) > *cur))//right child > cur
return false;
if (cur == first)
break;
}
return true;
}
template <class RandomAccessIterator>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last){
return TinySTL::is_heap(first, last,
TinySTL::less<typename TinySTL::iterator_traits<RandomAccessIterator>::value_type>());
}
//********** [all_of] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
bool all_of(InputIterator first, InputIterator last, UnaryPredicate pred){
for (; first != last; ++first){
if (!pred(*first))
return false;
}
return true;
}
//********** [any_of] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
bool any_of(InputIterator first, InputIterator last, UnaryPredicate pred){
for (; first != last; ++first){
if (pred(*first))
return true;
}
return false;
}
//********** [none_of] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
bool none_of(InputIterator first, InputIterator last, UnaryPredicate pred){
for (; first != last; ++first){
if (pred(*first))
return false;
}
return true;
}
//********** [for_each] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn){
for (; first != last; ++first)
fn(*first);
return fn;
}
//********** [find] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& val){
for (; first != last; ++first){
if (*first == val)
break;
}
return first;
}
//********** [find_if] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred){
for (; first != last; ++first){
if (pred(*first))
break;
}
return first;
}
//********** [find_if_not] *************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
InputIterator find_if_not(InputIterator first, InputIterator last, UnaryPredicate pred){
for (; first != last; ++first){
if (!pred(*first))
break;
}
return first;
}
//********** [find_end] ******************************
//********* [Algorithm Complexity: O(N*N)] ****************
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2){
if (first2 == last2)
return last1;
ForwardIterator1 ret = last1;
while (first1 != last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1 == *it2) {
++it1; ++it2;
if (it2 == last2) { ret = first1; break; }
if (it1 == last1) return ret;
}
++first1;
}
return ret;
}
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred){
if (first2 == last2)
return last1;
ForwardIterator1 ret = last1;
while (first1 != last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (pred(*it1, *it2)) {
++it1; ++it2;
if (it2 == last2) { ret = first1; break; }
if (it1 == last1) return ret;
}
++first1;
}
return ret;
}
//********** [find_first_of] ******************************
//********* [Algorithm Complexity: O(N*N)] ****************
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2){
for (; first1 != last1; ++first1){
for (auto it = first2; it != last2; ++it){
if (*first1 == *it)
return first1;
}
}
return last1;
}
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred){
for (; first1 != last1; ++first1){
for (auto it = first2; it != last2; ++it){
if (pred(*first1, *it))
return first1;
}
}
return last1;
}
//********** [adjacent_find] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred){
for (; first != last; ++first){
if (first + 1 != last && pred(*(first), *(first + 1)))
break;
}
return first;
}
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last){
return TinySTL::adjacent_find(first, last,
equal_to<typename iterator_traits<ForwardIterator>::value_type>());
}
//********** [count] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T& val){
typename iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; ++first){
if (*first == val)
++n;
}
return n;
}
//********** [count_if] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator, class UnaryPredicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, UnaryPredicate pred){
typename iterator_traits<InputIterator>::difference_type n = 0;
for (; first != last; ++first){
if (pred(*first))
++n;
}
return n;
}
//********** [mismatch] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2){
for (; first1 != last1; ++first1, ++first2){
if (*first1 != *first2)
break;
}
return TinySTL::make_pair(first1, first2);
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate pred){
for (; first1 != last1; ++first1, ++first2){
if (!pred(*first1, *first2))
break;
}
return TinySTL::make_pair(first1, first2);
}
//********** [equal] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate pred){
for (; first1 != last1; ++first1, ++first2){
if (!pred(*first1, *first2))
return false;
}
return true;
}
template <class InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2){
return TinySTL::equal(first1, last1, first2, TinySTL::equal_to<typename TinySTL::iterator_traits<InputIterator1>::value_type>());
}
//********** [is_permutation] ******************************
//********* [Algorithm Complexity: O(N*N)] ****************
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, BinaryPredicate pred){
//find the first position that is not equal
auto res = TinySTL::mismatch(first1, last1, first2, pred);
first1 = res.first, first2 = res.second;
if (first1 == last1)
return true;
auto last2 = first2;
std::advance(last2, std::distance(first1, last1));
for (auto it1 = first1; it1 != last1; ++it1){
if (TinySTL::find_if(first1, it1, [&](decltype(*first1) val){return pred(val, *it1); }) == it1){
auto n = TinySTL::count(first2, last2, *it1);
if (n == 0 || TinySTL::count(it1, last1, *it1) != n)
return false;
}
}
return true;
}
template <class ForwardIterator1, class ForwardIterator2>
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2){
return TinySTL::is_permutation(first1, last1, first2,
TinySTL::equal_to<typename TinySTL::iterator_traits<ForwardIterator1>::value_type>());
}
//********** [search] ******************************
//********* [Algorithm Complexity: O(N*N)] ****************
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred){
while (first1 != last1){
auto it1 = first1;
auto it2 = first2;
while (it1 != last1 && it2 != last2){
if (pred(*it1, *it2)){
++it1, ++it2;
}else{
break;
}
}
if (it2 == last2)
return first1;
if (it1 == last1)
return last1;
++first1;
}
return last1;
}
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2){
return TinySTL::search(first1, last1, first2, last2,
TinySTL::equal_to<typename TinySTL::iterator_traits<ForwardIterator1>::value_type>());
}
//********** [advance] ******************************
//********* [Algorithm Complexity: O(N)] ****************
namespace {
template<class InputIterator, class Distance>
void _advance(InputIterator& it, Distance n, input_iterator_tag){
assert(n >= 0);
while (n--){
++it;
}
}
template<class BidirectionIterator, class Distance>
void _advance(BidirectionIterator& it, Distance n, bidirectional_iterator_tag){
if (n < 0){
while (n++){
--it;
}
}else{
while (n--){
++it;
}
}
}
template<class RandomIterator, class Distance>
void _advance(RandomIterator& it, Distance n, random_access_iterator_tag){
if (n < 0){
it -= (-n);
}else{
it += n;
}
}
}
template <class InputIterator, class Distance>
void advance(InputIterator& it, Distance n){
typedef typename iterator_traits<InputIterator>::iterator_category iterator_category;
_advance(it, n, iterator_category());
}
//********** [sort] ******************************
//********* [Algorithm Complexity: O(NlogN)] ****************
namespace {
template<class RandomIterator, class BinaryPredicate>
typename iterator_traits<RandomIterator>::value_type
mid3(RandomIterator first, RandomIterator last, BinaryPredicate pred){//[first, last]
auto mid = first + (last + 1 - first) / 2;
if (pred(*mid, *first)){
std::swap(*mid, *first);
}
if (pred(*last, *mid)){
std::swap(*last, *mid);
}
if (pred(*last, *first)){
std::swap(*last, *first);
}
auto ret = *mid;
std::swap(*mid, *(last - 1));//��mid item��λ��Ϊ�ڱ�
return ret;
}
template<class RandomIterator, class BinaryPredicate>
void bubble_sort(RandomIterator first, RandomIterator last, BinaryPredicate pred){
auto len = last - first;
for (auto i = len; i != 0; --i){
bool swaped = false;
for (auto p = first; p != (first + i - 1); ++p){
if (pred(*(p + 1), *p)){
std::swap(*(p + 1), *p);
swaped = true;
}
}
if (!swaped)
break;
}
}
}
template<class RandomIterator>
void sort(RandomIterator first, RandomIterator last){
return sort(first, last, less<typename iterator_traits<RandomIterator>::value_type>());
}
template<class RandomIterator, class BinaryPredicate>
void sort(RandomIterator first, RandomIterator last, BinaryPredicate pred){
if (first >= last || first + 1 == last)
return;
if (last - first <= 20)//���䳤��С�ڵ���20�IJ���ð���������
return bubble_sort(first, last, pred);
auto mid = mid3(first, last - 1, pred);
auto p1 = first, p2 = last - 2;
while (p1 < p2){
while (pred(*p1, mid) && (p1 < p2)) ++p1;
while (!pred(*p2, mid) && (p1 < p2)) --p2;
if (p1 < p2){
std::swap(*p1, *p2);
}
}
std::swap(*p1, *(last - 2));//����Ϊ�ڱ���mid item����ԭ����λ��
sort(first, p1, pred);
sort(p1 + 1, last, pred);
}
//********** [generate] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template<class InputIterator, class Function>
void generate(InputIterator first, InputIterator last, Function func){
for (; first != last; ++first){
*first = func();
}
}
//********** [generate_n] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template <class OutputIterator, class Size, class Generator>
void generate_n(OutputIterator first, Size n, Generator gen){
while (n--){
*first = gen();
++first;
}
}
//********** [distance] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator first, InputIterator last, input_iterator_tag){
typename iterator_traits<InputIterator>::difference_type dist = 0;
while (first++ != last){
++dist;
}
return dist;
}
template<class RandomIterator>
typename iterator_traits<RandomIterator>::difference_type
_distance(RandomIterator first, RandomIterator last, random_access_iterator_tag){
auto dist = last - first;
return dist;
}
template<class Iterator>
typename iterator_traits<Iterator>::difference_type
distance(Iterator first, Iterator last){
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
return _distance(first, last, iterator_category());
}
//********** [copy] ******************************
//********* [Algorithm Complexity: O(N)] ****************
template<class InputIterator, class OutputIterator>
OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, _true_type){
auto dist = distance(first, last);
memcpy(result, first, sizeof(*first) * dist);
advance(result, dist);
return result;
}
template<class InputIterator, class OutputIterator>
OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator result, _false_type){
while (first != last){
*result = *first;
++result;
++first;
}
return result;
}
template<class InputIterator, class OutputIterator, class T>
OutputIterator _copy(InputIterator first, InputIterator last, OutputIterator result, T*){
typedef typename TinySTL::_type_traits<T>::is_POD_type is_pod;
return __copy(first, last, result, is_pod());
}
template <class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result){
return _copy(first, last, result, value_type(first));
}
template<>
inline char *copy(char *first, char *last, char *result){
auto dist = last - first;
memcpy(result, first, sizeof(*first) * dist);
return result + dist;
}
template<>
inline wchar_t *copy(wchar_t *first, wchar_t *last, wchar_t *result){
auto dist = last - first;
memcpy(result, first, sizeof(*first) * dist);
return result + dist;
}
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化