Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Manacker algorithm #27

Open
wants to merge 35 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4275bcc
Added TODO list
zamazan4ik Jul 23, 2016
697e816
Initialize Aho-Corasik
zamazan4ik Jul 26, 2016
f5681d8
Added return-reference find
zamazan4ik Jul 29, 2016
47778dd
New version of Aho-Corasick
zamazan4ik Aug 13, 2016
559ad90
Added guards and copyright
zamazan4ik Aug 13, 2016
1c64e19
Added example for Aho-Corasick
zamazan4ik Aug 13, 2016
19bc400
Added doxygen and documentation
zamazan4ik Aug 14, 2016
df8321a
Removed range interface for operator()
zamazan4ik Aug 14, 2016
14392f8
Added in doc 'insert' method
zamazan4ik Aug 15, 2016
4f325ae
Added tests.
zamazan4ik Aug 16, 2016
a40fe59
New version 'Aho-Corasick'
zamazan4ik Aug 24, 2016
a4dcb83
[micro] Fix doxygen comment
zamazan4ik Aug 24, 2016
98ec38a
Delete useless README
zamazan4ik Aug 24, 2016
ea9f65a
[micro] Fixed doxygen doc
zamazan4ik Aug 27, 2016
95ce8ab
Merged branch feature_branch/aho_corasik into feature_branch/aho_corasik
zamazan4ik Aug 27, 2016
a638394
[micro] Fixed C++11 compatibility and include guard name
zamazan4ik Aug 28, 2016
63c7077
[micro] Fixed comment
zamazan4ik Aug 28, 2016
517b6d5
Fix in matching patterns
zamazan4ik Aug 28, 2016
dbd435b
Fixed multiple init in 'find', renamed to aho_corasick
zamazan4ik Aug 31, 2016
3212f73
Added range-based 'find' .
zamazan4ik Sep 3, 2016
86e4514
Changed type of root std::unique_ptr<node_type> -> node_type
zamazan4ik Sep 3, 2016
3b37858
Deleted memory allocations.
zamazan4ik Sep 6, 2016
b6382e6
[micro] Refactoring
zamazan4ik Sep 13, 2016
ae8c3c3
Fix serious bug in searching.
zamazan4ik Sep 13, 2016
87117ce
Deleted std::map and std::unordered_map versions.
zamazan4ik Sep 15, 2016
48b2bc1
Fixed compile error
zamazan4ik Sep 17, 2016
47e6b97
Added source of implementation, refactoring
zamazan4ik Oct 7, 2016
903cb34
Init for Manacker's algorithm
zamazan4ik Oct 11, 2016
19c8292
Deleted trash
zamazan4ik Oct 11, 2016
fbe0764
Deleted some more trash
zamazan4ik Oct 11, 2016
b558132
Refactoring
zamazan4ik Oct 11, 2016
02d05af
[micro] Added reserving memory
zamazan4ik Nov 20, 2016
ddd3b61
Lazy Manacker
zamazan4ik Nov 25, 2016
9818a4c
Merge remote-tracking branch 'refs/remotes/origin/feature_branch/mana…
zamazan4ik Nov 25, 2016
754f025
Fixed potential erros
zamazan4ik Nov 27, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion example/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -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 ;


2 changes: 1 addition & 1 deletion include/boost/algorithm/is_palindrome.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
132 changes: 132 additions & 0 deletions include/boost/algorithm/manacker.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
Copyright (c) Alexander Zaitsev <[email protected]>, 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 <string>
#include <vector>
#include <utility>
#include <algorithm>

#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>

namespace boost { namespace algorithm {



template <typename Iter, typename BinaryPredicate = std::equal_to<typename std::iterator_traits<Iter>::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<typename Range>
manacker_class(const Range& r, BinaryPredicate p = BinaryPredicate())
: manacker_class(boost::begin(r), boost::end(r), p)
{
}

std::pair<Iter, Iter> next()
{
//if cannot find palindrome, returns {corp_end, corp_end}
std::pair<Iter, Iter> ans;
switch (flag_)
{
case 0:
ans = calcOdd(); break;
case 1:
ans = calcEven(); break;
default:
return std::pair<Iter, Iter>(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<Iter, Iter> 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<Iter, Iter>(begin_ + i - answer_[i], begin_ + i + answer_[i] + 1);
}

std::pair<Iter, Iter> 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<Iter, Iter>(end_, end_);
return std::pair<Iter, Iter>(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<int> answer_;
};


}}

#endif // BOOST_ALGORITHM_