diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index ce067cfeb..f81e01f26 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -20,5 +20,6 @@ project /boost/algorithm/example exe clamp_example : clamp_example.cpp ; exe search_example : search_example.cpp ; -exe is_palindrome_example : is_palindrome_example.cpp; +exe is_palindrome_example : is_palindrome_example.cpp ; + diff --git a/include/boost/algorithm/is_palindrome.hpp b/include/boost/algorithm/is_palindrome.hpp index 61acbae2e..217657013 100644 --- a/include/boost/algorithm/is_palindrome.hpp +++ b/include/boost/algorithm/is_palindrome.hpp @@ -61,7 +61,7 @@ bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predi /// \return true if the entire sequence is palindrome /// /// \param begin The start of the input sequence -/// \param end One past the end of the input sequence +/// \param end One past the end of the input sequence /// /// \note This function will return true for empty sequences and for palindromes. /// For other sequences function will return false. diff --git a/include/boost/algorithm/manacker.hpp b/include/boost/algorithm/manacker.hpp new file mode 100644 index 000000000..17ffe0496 --- /dev/null +++ b/include/boost/algorithm/manacker.hpp @@ -0,0 +1,132 @@ +/* + Copyright (c) Alexander Zaitsev , 2016 + Distributed under the Boost Software License, Version 1.0. (See + accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) + See http://www.boost.org/ for latest version. +*/ + +/// \file manacker.hpp +/// \brief Finds all palindromes in a sequence. +/// \author Alexander Zaitsev + +#ifndef BOOST_ALGORITHM_MANACKER_HPP +#define BOOST_ALGORITHM_MANACKER_HPP + +#include +#include +#include +#include + +#include +#include + +namespace boost { namespace algorithm { + + + +template ::value_type>> +class manacker_class +{ +public: + manacker_class(Iter begin, Iter end, BinaryPredicate p = BinaryPredicate()) + : begin_(begin), end_(end), p_(p) + { + length_ = std::distance(begin_, end_); + answer_.resize(length_); + } + + template + manacker_class(const Range& r, BinaryPredicate p = BinaryPredicate()) + : manacker_class(boost::begin(r), boost::end(r), p) + { + } + + std::pair next() + { + //if cannot find palindrome, returns {corp_end, corp_end} + std::pair ans; + switch (flag_) + { + case 0: + ans = calcOdd(); break; + case 1: + ans = calcEven(); break; + default: + return std::pair(end_, end_); + } + + ++i; + if(i == length_) + { + restoreToDefault(); + } + + return ans; + } +private: + void restoreToDefault() + { + ++flag_; + leftBorder = 0, rightBorder = -1, tempMirror = 0, i = 0; + std::fill(answer_.begin(), answer_.end(), 0); + } + + + std::pair calcOdd() + { + tempMirror = (i > rightBorder ? 0 : std::min(answer_[leftBorder + rightBorder - i], + rightBorder - i)) + 1;//find mirror of current index + while (i + tempMirror < length_ && i - tempMirror >= 0 && + p_(begin_[i - tempMirror], begin_[i + tempMirror]))//increase our index + { + ++tempMirror; + } + answer_[i] = --tempMirror; + if (i + tempMirror > rightBorder)//try to increase our right border of palindrom + { + leftBorder = i - tempMirror; + rightBorder = i + tempMirror; + } + return std::pair(begin_ + i - answer_[i], begin_ + i + answer_[i] + 1); + } + + std::pair calcEven() + { + for (; i < length_; ++i) + { + tempMirror = + (i > rightBorder ? 0 : std::min(answer_[leftBorder + rightBorder - i + 1], + rightBorder - i + 1)) + 1; + while (i + tempMirror - 1 < length_ && i - tempMirror >= 0 && + p_(begin_[i - tempMirror], begin_[i + tempMirror - 1])) + { + ++tempMirror; + } + answer_[i] = --tempMirror; + if (i + tempMirror - 1 > rightBorder) + { + leftBorder = i - tempMirror; + rightBorder = i + tempMirror - 1; + } + + if(answer_[i] != 0) + break; + } + if(i == length_) + return std::pair(end_, end_); + return std::pair(begin_ + i - answer_[i], begin_ + i + answer_[i]); + } +private: + Iter begin_, end_; + BinaryPredicate p_; + int length_, i = 0; + int leftBorder = 0, rightBorder = -1, tempMirror = 0, flag_ = 0; + + std::vector answer_; +}; + + +}} + +#endif // BOOST_ALGORITHM_ \ No newline at end of file