mirror of
https://github.com/boostorg/algorithm.git
synced 2025-07-06 09:16:33 +02:00
Initial checkin of Boost.Algorithm searching and clamp code and tests; docs and more Algos coming
[SVN r76388]
This commit is contained in:
22
example/Jamfile.v2
Normal file
22
example/Jamfile.v2
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Boost algorithm library example programs Jamfile
|
||||||
|
#
|
||||||
|
# Copyright Marshall Clow 2010-2012. Use, modification and
|
||||||
|
# distribution is subject to 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 updates, documentation, and revision history.
|
||||||
|
|
||||||
|
|
||||||
|
project /boost/algorithm/example
|
||||||
|
: requirements
|
||||||
|
<include>../../../
|
||||||
|
<optimization>speed
|
||||||
|
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||||
|
<toolset>msvc:<define>NOMINMAX
|
||||||
|
<link>static
|
||||||
|
:
|
||||||
|
;
|
||||||
|
|
||||||
|
exe clamp_example : clamp_example.cpp ;
|
||||||
|
exe search_example : search_example.cpp ;
|
54
example/clamp_example.cpp
Normal file
54
example/clamp_example.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream> // for cout, etc
|
||||||
|
|
||||||
|
#include <boost/algorithm/clamp.hpp>
|
||||||
|
|
||||||
|
namespace ba = boost::algorithm;
|
||||||
|
|
||||||
|
bool compare_string_lengths ( const std::string &one, const std::string &two )
|
||||||
|
{
|
||||||
|
return one.length () < two.length ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ( int /*argc*/, char * /*argv*/ [] ) {
|
||||||
|
// Clamp takes a value and two "fenceposts", and brings the value "between" the fenceposts.
|
||||||
|
|
||||||
|
// If the input value is "between" the fenceposts, then it is returned unchanged.
|
||||||
|
std::cout << "Clamping 5 to between [1, 10] -> " << ba::clamp ( 5, 1, 10 ) << std::endl;
|
||||||
|
|
||||||
|
// If the input value is out side the range of the fenceposts, it "brought into" range.
|
||||||
|
std::cout << "Clamping 15 to between [1, 10] -> " << ba::clamp ( 15, 1, 10 ) << std::endl;
|
||||||
|
std::cout << "Clamping -15 to between [1, 10] -> " << ba::clamp ( -15, 1, 10 ) << std::endl;
|
||||||
|
|
||||||
|
// It doesn't just work for ints
|
||||||
|
std::cout << "Clamping 5.1 to between [1, 10] -> " << ba::clamp ( 5.1, 1.0, 10.0 ) << std::endl;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string one ( "Lower Bound" ), two ( "upper bound!" ), test1 ( "test#" ), test2 ( "#test" );
|
||||||
|
std::cout << "Clamping '" << test1 << "' between ['" << one << "' and '" << two << "'] -> '" <<
|
||||||
|
ba::clamp ( test1, one, two ) << "'" << std::endl;
|
||||||
|
std::cout << "Clamping '" << test2 << "' between ['" << one << "' and '" << two << "'] -> '" <<
|
||||||
|
ba::clamp ( test2, one, two ) << "'" << std::endl;
|
||||||
|
// There is also a predicate based version, if you want to compare objects in your own way
|
||||||
|
std::cout << "Clamping '" << test1 << "' between ['" << one << "' and '" << two << "'] (comparing lengths) -> '" <<
|
||||||
|
ba::clamp ( test1, one, two, compare_string_lengths ) << "'" << std::endl;
|
||||||
|
std::cout << "Clamping '" << test2 << "' between ['" << one << "' and '" << two << "'] (comparing lengths) -> '" <<
|
||||||
|
ba::clamp ( test2, one, two, compare_string_lengths ) << "'" << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sometimes, though, you don't get quite what you expect
|
||||||
|
// This is because the two double arguments get converted to int
|
||||||
|
std::cout << "Somewhat unexpected: clamp ( 12, 14.7, 15.9 ) --> " << ba::clamp ( 12, 14.7, 15.9 ) << std::endl;
|
||||||
|
std::cout << "Expected: clamp ((double)12, 14.7, 15.9 ) --> " << ba::clamp ((double) 12, 14.7, 15.9 ) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
57
example/search_example.cpp
Normal file
57
example/search_example.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream> // for cout, etc.
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||||
|
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||||
|
|
||||||
|
namespace ba = boost::algorithm;
|
||||||
|
|
||||||
|
const std::string haystack ( "ABACAB is it everywhere!" );
|
||||||
|
const std::string needle1 ( "ACAB" );
|
||||||
|
const std::string needle2 ( "not ABA" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main ( int /*argc*/, char * /*argv*/ [] ) {
|
||||||
|
// In search.hpp, there are generic implementations of three classic sequence search
|
||||||
|
// algorithms. They all have the same (dual) interface.
|
||||||
|
|
||||||
|
// There is a procedural interface, based on std::search:
|
||||||
|
if ( ba::boyer_moore_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||||
|
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore 1)" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore 1)" << std::endl;
|
||||||
|
|
||||||
|
// If you plan on searching for the same pattern in several different data sets,
|
||||||
|
// you can create a search object and use that over and over again - amortizing the setup
|
||||||
|
// costs across several searches
|
||||||
|
ba::boyer_moore<std::string::const_iterator> search1 ( needle1.begin (), needle1.end ());
|
||||||
|
if ( search1 ( haystack.begin (), haystack.end ()) != haystack.end ())
|
||||||
|
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore 2)" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore 2)" << std::endl;
|
||||||
|
|
||||||
|
// There is also an implementation of boyer-moore-horspool searching
|
||||||
|
if ( ba::boyer_moore_horspool_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||||
|
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore-horspool)" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore-horspool)" << std::endl;
|
||||||
|
|
||||||
|
// And also the knuth-pratt-morris search algorithm
|
||||||
|
if ( ba::knuth_morris_pratt_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||||
|
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (knuth_morris_pratt)" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (knuth_morris_pratt)" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
175
include/boost/algorithm/clamp.hpp
Executable file
175
include/boost/algorithm/clamp.hpp
Executable file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2008-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
Revision history:
|
||||||
|
27 June 2009 mtc First version
|
||||||
|
23 Oct 2010 mtc Added predicate version
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// \file clamp.hpp
|
||||||
|
/// \brief Clamp algorithm
|
||||||
|
/// \author Marshall Clow
|
||||||
|
///
|
||||||
|
/// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_CLAMP_HPP
|
||||||
|
#define BOOST_ALGORITHM_CLAMP_HPP
|
||||||
|
|
||||||
|
#include <functional> // For std::less
|
||||||
|
#include <iterator> // For std::iterator_traits
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
#include <boost/mpl/identity.hpp> // for identity
|
||||||
|
#include <boost/utility/enable_if.hpp> // for boost::disable_if
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm {
|
||||||
|
|
||||||
|
/// \fn clamp ( T const& val,
|
||||||
|
/// typename boost::mpl::identity<T>::type const& lo,
|
||||||
|
/// typename boost::mpl::identity<T>::type const& hi, Pred p )
|
||||||
|
/// \return the value "val" brought into the range [ lo, hi ]
|
||||||
|
/// using the comparison predicate p.
|
||||||
|
/// If p ( val, lo ) return lo.
|
||||||
|
/// If p ( hi, val ) return hi.
|
||||||
|
/// Otherwise, return the original value.
|
||||||
|
///
|
||||||
|
/// \param val The value to be clamped
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
/// \param p A predicate to use to compare the values.
|
||||||
|
/// p ( a, b ) returns a boolean.
|
||||||
|
///
|
||||||
|
template<typename T, typename Pred>
|
||||||
|
T const & clamp ( T const& val,
|
||||||
|
typename boost::mpl::identity<T>::type const & lo,
|
||||||
|
typename boost::mpl::identity<T>::type const & hi, Pred p )
|
||||||
|
{
|
||||||
|
// assert ( !p ( hi, lo )); // Can't assert p ( lo, hi ) b/c they might be equal
|
||||||
|
return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \fn clamp ( T const& val,
|
||||||
|
/// typename boost::mpl::identity<T>::type const& lo,
|
||||||
|
/// typename boost::mpl::identity<T>::type const& hi )
|
||||||
|
/// \return the value "val" brought into the range [ lo, hi ].
|
||||||
|
/// If the value is less than lo, return lo.
|
||||||
|
/// If the value is greater than "hi", return hi.
|
||||||
|
/// Otherwise, return the original value.
|
||||||
|
///
|
||||||
|
/// \param val The value to be clamped
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
///
|
||||||
|
template<typename T>
|
||||||
|
T const& clamp ( const T& val,
|
||||||
|
typename boost::mpl::identity<T>::type const & lo,
|
||||||
|
typename boost::mpl::identity<T>::type const & hi )
|
||||||
|
{
|
||||||
|
return (clamp) ( val, lo, hi, std::less<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
|
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||||
|
/// std::iterator_traits<InputIterator>::value_type hi )
|
||||||
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
|
///
|
||||||
|
/// \param first The start of the range of values
|
||||||
|
/// \param last One past the end of the range of input values
|
||||||
|
/// \param out An output iterator to write the clamped values into
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
///
|
||||||
|
template<typename InputIterator, typename OutputIterator>
|
||||||
|
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
|
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||||
|
typename std::iterator_traits<InputIterator>::value_type hi )
|
||||||
|
{
|
||||||
|
// this could also be written with bind and std::transform
|
||||||
|
while ( first != last )
|
||||||
|
*out++ = clamp ( *first++, lo, hi );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||||
|
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||||
|
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||||
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
|
///
|
||||||
|
/// \param r The range of values to be clamped
|
||||||
|
/// \param out An output iterator to write the clamped values into
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
///
|
||||||
|
template<typename Range, typename OutputIterator>
|
||||||
|
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||||
|
clamp_range ( const Range &r, OutputIterator out,
|
||||||
|
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||||
|
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||||
|
{
|
||||||
|
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
|
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||||
|
/// std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||||
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
|
/// using the comparison predicate p.
|
||||||
|
///
|
||||||
|
/// \param first The start of the range of values
|
||||||
|
/// \param last One past the end of the range of input values
|
||||||
|
/// \param out An output iterator to write the clamped values into
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
/// \param p A predicate to use to compare the values.
|
||||||
|
/// p ( a, b ) returns a boolean.
|
||||||
|
|
||||||
|
///
|
||||||
|
template<typename InputIterator, typename OutputIterator, typename Pred>
|
||||||
|
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
|
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||||
|
typename std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||||
|
{
|
||||||
|
// this could also be written with bind and std::transform
|
||||||
|
while ( first != last )
|
||||||
|
*out++ = clamp ( *first++, lo, hi, p );
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||||
|
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||||
|
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||||
|
/// Pred p )
|
||||||
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
|
/// using the comparison predicate p.
|
||||||
|
///
|
||||||
|
/// \param r The range of values to be clamped
|
||||||
|
/// \param out An output iterator to write the clamped values into
|
||||||
|
/// \param lo The lower bound of the range to be clamped to
|
||||||
|
/// \param hi The upper bound of the range to be clamped to
|
||||||
|
/// \param p A predicate to use to compare the values.
|
||||||
|
/// p ( a, b ) returns a boolean.
|
||||||
|
//
|
||||||
|
// Disable this template if the first two parameters are the same type;
|
||||||
|
// In that case, the user will get the two iterator version.
|
||||||
|
template<typename Range, typename OutputIterator, typename Pred>
|
||||||
|
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||||
|
clamp_range ( const Range &r, OutputIterator out,
|
||||||
|
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||||
|
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||||
|
Pred p )
|
||||||
|
{
|
||||||
|
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_CLAMP_HPP
|
268
include/boost/algorithm/searching/boyer_moore.hpp
Executable file
268
include/boost/algorithm/searching/boyer_moore.hpp
Executable file
@ -0,0 +1,268 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||||
|
#define BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||||
|
|
||||||
|
#include <iterator> // for std::iterator_traits
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
#include <boost/range/begin.hpp>
|
||||||
|
#include <boost/range/end.hpp>
|
||||||
|
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||||
|
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm {
|
||||||
|
|
||||||
|
/*
|
||||||
|
A templated version of the boyer-moore searching algorithm.
|
||||||
|
|
||||||
|
References:
|
||||||
|
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/
|
||||||
|
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
|
||||||
|
|
||||||
|
Explanations: boostinspect:noascii (test tool complains)
|
||||||
|
http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm
|
||||||
|
http://www.movsd.com/bm.htm
|
||||||
|
http://www.cs.ucdavis.edu/~gusfield/cs224f09/bnotes.pdf
|
||||||
|
|
||||||
|
The Boyer-Moore search algorithm uses two tables, a "bad character" table
|
||||||
|
to tell how far to skip ahead when it hits a character that is not in the pattern,
|
||||||
|
and a "good character" table to tell how far to skip ahead when it hits a
|
||||||
|
mismatch on a character that _is_ in the pattern.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
* Random access iterators
|
||||||
|
* The two iterator types (patIter and corpusIter) must
|
||||||
|
"point to" the same underlying type and be comparable.
|
||||||
|
* Additional requirements may be imposed but the skip table, such as:
|
||||||
|
** Numeric type (array-based skip table)
|
||||||
|
** Hashable type (map-based skip table)
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||||
|
class boyer_moore {
|
||||||
|
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||||
|
public:
|
||||||
|
boyer_moore ( patIter first, patIter last )
|
||||||
|
: pat_first ( first ), pat_last ( last ),
|
||||||
|
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||||
|
skip_ ( k_pattern_length, -1 ),
|
||||||
|
suffix_ ( k_pattern_length + 1 )
|
||||||
|
{
|
||||||
|
this->build_skip_table ( first, last );
|
||||||
|
this->build_suffix_table ( first, last );
|
||||||
|
}
|
||||||
|
|
||||||
|
~boyer_moore () {}
|
||||||
|
|
||||||
|
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||||
|
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||||
|
typename std::iterator_traits<patIter>::value_type,
|
||||||
|
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||||
|
|
||||||
|
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||||
|
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||||
|
|
||||||
|
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||||
|
// If the pattern is larger than the corpus, we can't find it!
|
||||||
|
if ( k_corpus_length < k_pattern_length )
|
||||||
|
return corpus_last;
|
||||||
|
|
||||||
|
// Do the search
|
||||||
|
return this->do_search ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Range>
|
||||||
|
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
|
||||||
|
return (*this) (boost::begin(r), boost::end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \cond DOXYGEN_HIDE
|
||||||
|
patIter pat_first, pat_last;
|
||||||
|
const difference_type k_pattern_length;
|
||||||
|
typename traits::skip_table_t skip_;
|
||||||
|
std::vector <difference_type> suffix_;
|
||||||
|
|
||||||
|
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param p A predicate used for the search comparisons.
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||||
|
/* ---- Do the matching ---- */
|
||||||
|
corpusIter curPos = corpus_first;
|
||||||
|
const corpusIter lastPos = corpus_last - k_pattern_length;
|
||||||
|
difference_type j, k, m;
|
||||||
|
|
||||||
|
while ( curPos <= lastPos ) {
|
||||||
|
/* while ( std::distance ( curPos, corpus_last ) >= k_pattern_length ) { */
|
||||||
|
// Do we match right where we are?
|
||||||
|
j = k_pattern_length;
|
||||||
|
while ( pat_first [j-1] == curPos [j-1] ) {
|
||||||
|
j--;
|
||||||
|
// We matched - we're done!
|
||||||
|
if ( j == 0 )
|
||||||
|
return curPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we didn't match, figure out how far to skip forward
|
||||||
|
k = skip_ [ curPos [ j - 1 ]];
|
||||||
|
m = j - k - 1;
|
||||||
|
if ( k < j && m > suffix_ [ j ] )
|
||||||
|
curPos += m;
|
||||||
|
else
|
||||||
|
curPos += suffix_ [ j ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return corpus_last; // We didn't find anything
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void build_skip_table ( patIter first, patIter last ) {
|
||||||
|
for ( std::size_t i = 0; first != last; ++first, ++i )
|
||||||
|
skip_.insert ( *first, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Iter, typename Container>
|
||||||
|
void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) {
|
||||||
|
const std::size_t count = std::distance ( pat_first, pat_last );
|
||||||
|
BOOST_ASSERT ( count > 0 );
|
||||||
|
BOOST_ASSERT ( prefix.size () == count );
|
||||||
|
|
||||||
|
prefix[0] = 0;
|
||||||
|
std::size_t k = 0;
|
||||||
|
for ( std::size_t i = 1; i < count; ++i ) {
|
||||||
|
BOOST_ASSERT ( k < count );
|
||||||
|
while ( k > 0 && ( pat_first[k] != pat_first[i] )) {
|
||||||
|
BOOST_ASSERT ( k < count );
|
||||||
|
k = prefix [ k - 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pat_first[k] == pat_first[i] )
|
||||||
|
k++;
|
||||||
|
prefix [ i ] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_suffix_table ( patIter pat_first, patIter pat_last ) {
|
||||||
|
const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last );
|
||||||
|
|
||||||
|
if ( count > 0 ) { // empty pattern
|
||||||
|
std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count);
|
||||||
|
(void) std::reverse_copy ( pat_first, pat_last, reversed.begin ());
|
||||||
|
|
||||||
|
std::vector<difference_type> prefix (count);
|
||||||
|
compute_bm_prefix ( pat_first, pat_last, prefix );
|
||||||
|
|
||||||
|
std::vector<difference_type> prefix_reversed (count);
|
||||||
|
compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed );
|
||||||
|
|
||||||
|
for ( std::size_t i = 0; i <= count; i++ )
|
||||||
|
suffix_[i] = count - prefix [count-1];
|
||||||
|
|
||||||
|
for ( std::size_t i = 0; i < count; i++ ) {
|
||||||
|
const std::size_t j = count - prefix_reversed[i];
|
||||||
|
const difference_type k = i - prefix_reversed[i] + 1;
|
||||||
|
|
||||||
|
if (suffix_[j] > k)
|
||||||
|
suffix_[j] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
|
||||||
|
Use a bit of TMP to disambiguate the 3-argument templates */
|
||||||
|
|
||||||
|
/// \fn boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
/// patIter pat_first, patIter pat_last )
|
||||||
|
/// \brief Searches the corpus for the pattern.
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||||
|
/// \param pat_last One past the end of the data to search for
|
||||||
|
///
|
||||||
|
template <typename patIter, typename corpusIter>
|
||||||
|
corpusIter boyer_moore_search (
|
||||||
|
corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
patIter pat_first, patIter pat_last )
|
||||||
|
{
|
||||||
|
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||||
|
return bm ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PatternRange, typename corpusIter>
|
||||||
|
corpusIter boyer_moore_search (
|
||||||
|
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
|
||||||
|
{
|
||||||
|
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
|
||||||
|
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||||
|
return bm ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename patIter, typename CorpusRange>
|
||||||
|
typename boost::lazy_disable_if_c<
|
||||||
|
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
|
||||||
|
::type
|
||||||
|
boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
|
||||||
|
{
|
||||||
|
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||||
|
return bm (boost::begin (corpus), boost::end (corpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PatternRange, typename CorpusRange>
|
||||||
|
typename boost::range_iterator<CorpusRange>::type
|
||||||
|
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
|
||||||
|
{
|
||||||
|
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
|
||||||
|
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||||
|
return bm (boost::begin (corpus), boost::end (corpus));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Creator functions -- take a pattern range, return an object
|
||||||
|
template <typename Range>
|
||||||
|
boost::algorithm::boyer_moore<typename boost::range_iterator<const Range>::type>
|
||||||
|
make_boyer_moore ( const Range &r ) {
|
||||||
|
return boost::algorithm::boyer_moore
|
||||||
|
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Range>
|
||||||
|
boost::algorithm::boyer_moore<typename boost::range_iterator<Range>::type>
|
||||||
|
make_boyer_moore ( Range &r ) {
|
||||||
|
return boost::algorithm::boyer_moore
|
||||||
|
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
141
include/boost/algorithm/searching/boyer_moore_horspool.hpp
Executable file
141
include/boost/algorithm/searching/boyer_moore_horspool.hpp
Executable file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||||
|
#define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||||
|
|
||||||
|
#include <iterator> // for std::iterator_traits
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||||
|
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||||
|
|
||||||
|
// #define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm {
|
||||||
|
|
||||||
|
/*
|
||||||
|
A templated version of the boyer-moore-horspool searching algorithm.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
* Random access iterators
|
||||||
|
* The two iterator types (patIter and corpusIter) must
|
||||||
|
"point to" the same underlying type.
|
||||||
|
* Additional requirements may be imposed buy the skip table, such as:
|
||||||
|
** Numeric type (array-based skip table)
|
||||||
|
** Hashable type (map-based skip table)
|
||||||
|
|
||||||
|
http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||||
|
class boyer_moore_horspool {
|
||||||
|
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||||
|
public:
|
||||||
|
boyer_moore_horspool ( patIter first, patIter last )
|
||||||
|
: pat_first ( first ), pat_last ( last ),
|
||||||
|
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||||
|
skip_ ( k_pattern_length, k_pattern_length ) {
|
||||||
|
|
||||||
|
// Build the skip table
|
||||||
|
std::size_t i = 0;
|
||||||
|
if ( first != last ) // empty pattern?
|
||||||
|
for ( patIter iter = first; iter != last-1; ++iter, ++i )
|
||||||
|
skip_.insert ( *iter, k_pattern_length - 1 - i );
|
||||||
|
#ifdef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||||
|
skip_.PrintSkipTable ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~boyer_moore_horspool () {}
|
||||||
|
|
||||||
|
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param p A predicate used for the search comparisons.
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||||
|
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||||
|
typename std::iterator_traits<patIter>::value_type,
|
||||||
|
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||||
|
|
||||||
|
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||||
|
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||||
|
|
||||||
|
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||||
|
// If the pattern is larger than the corpus, we can't find it!
|
||||||
|
if ( k_corpus_length < k_pattern_length )
|
||||||
|
return corpus_last;
|
||||||
|
|
||||||
|
// Do the search
|
||||||
|
return this->do_search ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \cond DOXYGEN_HIDE
|
||||||
|
patIter pat_first, pat_last;
|
||||||
|
const difference_type k_pattern_length;
|
||||||
|
typename traits::skip_table_t skip_;
|
||||||
|
|
||||||
|
/// \fn do_search ( corpusIter corpus_first, corpusIter corpus_last )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param k_corpus_length The length of the corpus to search
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||||
|
corpusIter curPos = corpus_first;
|
||||||
|
const corpusIter lastPos = corpus_last - k_pattern_length;
|
||||||
|
while ( curPos <= lastPos ) {
|
||||||
|
// Do we match right where we are?
|
||||||
|
std::size_t j = k_pattern_length - 1;
|
||||||
|
while ( pat_first [j] == curPos [j] ) {
|
||||||
|
// We matched - we're done!
|
||||||
|
if ( j == 0 )
|
||||||
|
return curPos;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
curPos += skip_ [ curPos [ k_pattern_length - 1 ]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return corpus_last;
|
||||||
|
}
|
||||||
|
// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
/// patIter pat_first, patIter pat_last )
|
||||||
|
/// \brief Searches the corpus for the pattern.
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||||
|
/// \param pat_last One past the end of the data to search for
|
||||||
|
///
|
||||||
|
template <typename patIter, typename corpusIter>
|
||||||
|
corpusIter boyer_moore_horspool_search (
|
||||||
|
corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
patIter pat_first, patIter pat_last ) {
|
||||||
|
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
|
||||||
|
return bmh ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
105
include/boost/algorithm/searching/detail/bm_traits.hpp
Executable file
105
include/boost/algorithm/searching/detail/bm_traits.hpp
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||||
|
#define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <climits> // for CHAR_BIT
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator> // for std::iterator_traits
|
||||||
|
|
||||||
|
#include <boost/type_traits/make_unsigned.hpp>
|
||||||
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
|
#include <boost/type_traits/remove_pointer.hpp>
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/tr1/tr1/unordered_map>
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm { namespace detail {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default implementations of the skip tables for B-M and B-M-H
|
||||||
|
//
|
||||||
|
template<typename key_type, typename value_type, bool /*useArray*/> class skip_table;
|
||||||
|
|
||||||
|
// General case for data searching other than bytes; use a map
|
||||||
|
template<typename key_type, typename value_type>
|
||||||
|
class skip_table<key_type, value_type, false> {
|
||||||
|
private:
|
||||||
|
typedef std::tr1::unordered_map<key_type, value_type> skip_map;
|
||||||
|
const value_type k_default_value;
|
||||||
|
skip_map skip_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
skip_table ( std::size_t patSize, value_type default_value )
|
||||||
|
: k_default_value ( default_value ), skip_ ( patSize ) {}
|
||||||
|
|
||||||
|
void insert ( key_type key, value_type val ) {
|
||||||
|
skip_ [ key ] = val; // Would skip_.insert (val) be better here?
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator [] ( key_type key ) const {
|
||||||
|
typename skip_map::const_iterator it = skip_.find ( key );
|
||||||
|
return it == skip_.end () ? k_default_value : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintSkipTable () const {
|
||||||
|
std::cout << "BM(H) Skip Table <unordered_map>:" << std::endl;
|
||||||
|
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||||
|
if ( it->second != k_default_value )
|
||||||
|
std::cout << " " << it->first << ": " << it->second << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Special case small numeric values; use an array
|
||||||
|
template<typename key_type, typename value_type>
|
||||||
|
class skip_table<key_type, value_type, true> {
|
||||||
|
private:
|
||||||
|
typedef typename boost::make_unsigned<key_type>::type unsigned_key_type;
|
||||||
|
typedef boost::array<value_type, 1U << (CHAR_BIT * sizeof(key_type))> skip_map;
|
||||||
|
skip_map skip_;
|
||||||
|
const value_type k_default_value;
|
||||||
|
public:
|
||||||
|
skip_table ( std::size_t patSize, value_type default_value ) : k_default_value ( default_value ) {
|
||||||
|
std::fill_n ( skip_.begin(), skip_.size(), default_value );
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert ( key_type key, value_type val ) {
|
||||||
|
skip_ [ static_cast<unsigned_key_type> ( key ) ] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator [] ( key_type key ) const {
|
||||||
|
return skip_ [ static_cast<unsigned_key_type> ( key ) ];
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintSkipTable () const {
|
||||||
|
std::cout << "BM(H) Skip Table <boost:array>:" << std::endl;
|
||||||
|
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||||
|
if ( *it != k_default_value )
|
||||||
|
std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
struct BM_traits {
|
||||||
|
typedef typename std::iterator_traits<Iterator>::difference_type value_type;
|
||||||
|
typedef typename std::iterator_traits<Iterator>::value_type key_type;
|
||||||
|
typedef boost::algorithm::detail::skip_table<key_type, value_type,
|
||||||
|
boost::is_integral<key_type>::value && (sizeof(key_type)==1)> skip_table_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
}}} // namespaces
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
30
include/boost/algorithm/searching/detail/debugging.hpp
Executable file
30
include/boost/algorithm/searching/detail/debugging.hpp
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||||
|
#define BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
/// \cond DOXYGEN_HIDE
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm { namespace detail {
|
||||||
|
|
||||||
|
// Debugging support
|
||||||
|
template <typename Iter>
|
||||||
|
void PrintTable ( Iter first, Iter last ) {
|
||||||
|
std::cout << std::distance ( first, last ) << ": { ";
|
||||||
|
for ( Iter iter = first; iter != last; ++iter )
|
||||||
|
std::cout << *iter << " ";
|
||||||
|
std::cout << "}" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}}}
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
200
include/boost/algorithm/searching/knuth_morris_pratt.hpp
Executable file
200
include/boost/algorithm/searching/knuth_morris_pratt.hpp
Executable file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||||
|
#define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator> // for std::iterator_traits
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||||
|
|
||||||
|
// #define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||||
|
|
||||||
|
namespace boost { namespace algorithm {
|
||||||
|
|
||||||
|
// #define NEW_KMP
|
||||||
|
|
||||||
|
/*
|
||||||
|
A templated version of the Knuth-Morris-Pratt searching algorithm.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
* Random-access iterators
|
||||||
|
* The two iterator types (I1 and I2) must "point to" the same underlying type.
|
||||||
|
|
||||||
|
http://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm
|
||||||
|
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename patIter>
|
||||||
|
class knuth_morris_pratt {
|
||||||
|
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||||
|
public:
|
||||||
|
knuth_morris_pratt ( patIter first, patIter last )
|
||||||
|
: pat_first ( first ), pat_last ( last ),
|
||||||
|
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||||
|
skip_ ( k_pattern_length + 1 ) {
|
||||||
|
#ifdef NEW_KMP
|
||||||
|
preKmp ( pat_first, pat_last );
|
||||||
|
#else
|
||||||
|
init_skip_table ( pat_first, pat_last );
|
||||||
|
#endif
|
||||||
|
#ifdef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||||
|
detail::PrintTable ( skip_.begin (), skip_.end ());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
~knuth_morris_pratt () {}
|
||||||
|
|
||||||
|
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param p A predicate used for the search comparisons.
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||||
|
BOOST_STATIC_ASSERT (( boost::is_same<
|
||||||
|
typename std::iterator_traits<patIter>::value_type,
|
||||||
|
typename std::iterator_traits<corpusIter>::value_type>::value ));
|
||||||
|
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
|
||||||
|
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
|
||||||
|
|
||||||
|
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
|
||||||
|
// If the pattern is larger than the corpus, we can't find it!
|
||||||
|
if ( k_corpus_length < k_pattern_length )
|
||||||
|
return corpus_last;
|
||||||
|
|
||||||
|
return do_search ( corpus_first, corpus_last, k_corpus_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \cond DOXYGEN_HIDE
|
||||||
|
patIter pat_first, pat_last;
|
||||||
|
const difference_type k_pattern_length;
|
||||||
|
std::vector <difference_type> skip_;
|
||||||
|
|
||||||
|
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||||
|
/// \brief Searches the corpus for the pattern that was passed into the constructor
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param p A predicate used for the search comparisons.
|
||||||
|
///
|
||||||
|
template <typename corpusIter>
|
||||||
|
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
difference_type k_corpus_length ) const {
|
||||||
|
difference_type match_start = 0; // position in the corpus that we're matching
|
||||||
|
|
||||||
|
#ifdef NEW_KMP
|
||||||
|
int patternIdx = 0;
|
||||||
|
while ( match_start < k_corpus_length ) {
|
||||||
|
while ( patternIdx > -1 && pat_first[patternIdx] != corpus_first [match_start] )
|
||||||
|
patternIdx = skip_ [patternIdx]; //<--- Shifting the pattern on mismatch
|
||||||
|
|
||||||
|
patternIdx++;
|
||||||
|
match_start++; //<--- corpus is always increased by 1
|
||||||
|
|
||||||
|
if ( patternIdx >= (int) k_pattern_length )
|
||||||
|
return corpus_first + match_start - patternIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
// At this point, we know:
|
||||||
|
// k_pattern_length <= k_corpus_length
|
||||||
|
// for all elements of skip, it holds -1 .. k_pattern_length
|
||||||
|
//
|
||||||
|
// In the loop, we have the following invariants
|
||||||
|
// idx is in the range 0 .. k_pattern_length
|
||||||
|
// match_start is in the range 0 .. k_corpus_length - k_pattern_length + 1
|
||||||
|
|
||||||
|
const difference_type last_match = k_corpus_length - k_pattern_length;
|
||||||
|
difference_type idx = 0; // position in the pattern we're comparing
|
||||||
|
|
||||||
|
while ( match_start <= last_match ) {
|
||||||
|
while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) {
|
||||||
|
if ( ++idx == k_pattern_length )
|
||||||
|
return corpus_first + match_start;
|
||||||
|
}
|
||||||
|
// Figure out where to start searching again
|
||||||
|
// assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward
|
||||||
|
match_start += idx - skip_ [ idx ];
|
||||||
|
idx = skip_ [ idx ] >= 0 ? skip_ [ idx ] : 0;
|
||||||
|
// assert ( idx >= 0 && idx < k_pattern_length );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// We didn't find anything
|
||||||
|
return corpus_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void preKmp ( patIter first, patIter last ) {
|
||||||
|
const /*std::size_t*/ int count = std::distance ( first, last );
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
j = skip_[0] = -1;
|
||||||
|
while (i < count) {
|
||||||
|
while (j > -1 && first[i] != first[j])
|
||||||
|
j = skip_[j];
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
if (first[i] == first[j])
|
||||||
|
skip_[i] = skip_[j];
|
||||||
|
else
|
||||||
|
skip_[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void init_skip_table ( patIter first, patIter last ) {
|
||||||
|
const difference_type count = std::distance ( first, last );
|
||||||
|
|
||||||
|
int j;
|
||||||
|
skip_ [ 0 ] = -1;
|
||||||
|
for ( int i = 1; i <= count; ++i ) {
|
||||||
|
j = skip_ [ i - 1 ];
|
||||||
|
while ( j >= 0 ) {
|
||||||
|
if ( first [ j ] == first [ i - 1 ] )
|
||||||
|
break;
|
||||||
|
j = skip_ [ j ];
|
||||||
|
}
|
||||||
|
skip_ [ i ] = j + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// \endcond
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
/// patIter pat_first, patIter pat_last )
|
||||||
|
/// \brief Searches the corpus for the pattern.
|
||||||
|
///
|
||||||
|
/// \param corpus_first The start of the data to search (Random Access Iterator)
|
||||||
|
/// \param corpus_last One past the end of the data to search
|
||||||
|
/// \param pat_first The start of the pattern to search for (Random Access Iterator)
|
||||||
|
/// \param pat_last One past the end of the data to search for
|
||||||
|
///
|
||||||
|
template <typename patIter, typename corpusIter>
|
||||||
|
corpusIter knuth_morris_pratt_search (
|
||||||
|
corpusIter corpus_first, corpusIter corpus_last,
|
||||||
|
patIter pat_first, patIter pat_last ) {
|
||||||
|
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
|
||||||
|
return kmp ( corpus_first, corpus_last );
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
27
test/Jamfile.v2
Executable file
27
test/Jamfile.v2
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
# Boost algorithm library test suite Jamfile ----------------------------
|
||||||
|
#
|
||||||
|
# Copyright Marshall Clow 2010-2012. Use, modification and
|
||||||
|
# distribution is subject to 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 updates, documentation, and revision history.
|
||||||
|
|
||||||
|
import testing ;
|
||||||
|
|
||||||
|
{
|
||||||
|
test-suite algorithm:
|
||||||
|
# Search tests
|
||||||
|
: [ run empty_search_test.cpp : : : : empty_search_test ]
|
||||||
|
[ run search_test1.cpp : : : : search_test1 ]
|
||||||
|
[ run search_test2.cpp : : : : search_test2 ]
|
||||||
|
[ run search_test3.cpp : : : : search_test3 ]
|
||||||
|
[ compile-fail search_fail1.cpp : : : : ]
|
||||||
|
[ compile-fail search_fail2.cpp : : : : ]
|
||||||
|
[ compile-fail search_fail3.cpp : : : : ]
|
||||||
|
|
||||||
|
# Clamp tests
|
||||||
|
[ run clamp_test.cpp : : : : clamp_test ]
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
218
test/clamp_test.cpp
Executable file
218
test/clamp_test.cpp
Executable file
@ -0,0 +1,218 @@
|
|||||||
|
// (C) Copyright Jesse Williamson 2009
|
||||||
|
// Use, modification and distribution are subject to 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)
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/algorithm/clamp.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/test_exec_monitor.hpp>
|
||||||
|
|
||||||
|
namespace ba = boost::algorithm;
|
||||||
|
|
||||||
|
bool intGreater ( int lhs, int rhs ) { return lhs > rhs; }
|
||||||
|
bool doubleGreater ( double lhs, double rhs ) { return lhs > rhs; }
|
||||||
|
|
||||||
|
class custom {
|
||||||
|
public:
|
||||||
|
custom ( int x ) : v(x) {}
|
||||||
|
custom ( const custom &rhs ) : v(rhs.v) {}
|
||||||
|
~custom () {}
|
||||||
|
custom & operator = ( const custom &rhs ) { v = rhs.v; return *this; }
|
||||||
|
|
||||||
|
bool operator < ( const custom &rhs ) const { return v < rhs.v; }
|
||||||
|
bool operator == ( const custom &rhs ) const { return v == rhs.v; } // need this for the test
|
||||||
|
|
||||||
|
std::ostream & print ( std::ostream &os ) const { return os << v; }
|
||||||
|
|
||||||
|
int v;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream & operator << ( std::ostream & os, const custom &x ) { return x.print ( os ); }
|
||||||
|
|
||||||
|
bool customLess ( const custom &lhs, const custom &rhs ) { return lhs.v < rhs.v; }
|
||||||
|
|
||||||
|
void test_ints()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Inside the range, equal to the endpoints, and outside the endpoints.
|
||||||
|
BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 1, 10 ));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 10, 1, intGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 10, 1, intGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 10, 1, intGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 10, 1, intGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 10, 1, intGreater ));
|
||||||
|
|
||||||
|
// Negative numbers
|
||||||
|
BOOST_CHECK_EQUAL ( -3, ba::clamp ( -3, -10, -1 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -1, ba::clamp ( -1, -10, -1 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -1, ba::clamp ( 0, -10, -1 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -10, -10, -1 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -11, -10, -1 ));
|
||||||
|
|
||||||
|
// Mixed positive and negative numbers
|
||||||
|
BOOST_CHECK_EQUAL ( 5, ba::clamp ( 5, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -10, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10, ba::clamp ( -15, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 15, -10, 10 ));
|
||||||
|
|
||||||
|
// Unsigned
|
||||||
|
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1U, 10U ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1U, 10U ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1U, 10U ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1U, 10U ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1U, 10U ));
|
||||||
|
|
||||||
|
// Mixed (1)
|
||||||
|
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1, 10 ));
|
||||||
|
|
||||||
|
// Mixed (3)
|
||||||
|
BOOST_CHECK_EQUAL ( 5U, ba::clamp ( 5U, 1, 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 1U, 1, 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1U, ba::clamp ( 0U, 1, 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 10U, 1, 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10U, ba::clamp ( 15U, 1, 10. ));
|
||||||
|
|
||||||
|
short foo = 50;
|
||||||
|
BOOST_CHECK_EQUAL ( 56, ba::clamp ( foo, 56.9, 129 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 24910, ba::clamp ( foo, 12345678, 123456999 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_floats()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Inside the range, equal to the endpoints, and outside the endpoints.
|
||||||
|
BOOST_CHECK_EQUAL ( 3.0, ba::clamp ( 3.0, 1.0, 10.0 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 1.0, 1.0, 10.0 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 0.0, 1.0, 10.0 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 10.0, 1.0, 10.0 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 11.0, 1.0, 10.0 ));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( 3.0, ba::clamp ( 3.0, 10.0, 1.0, doubleGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 1.0, 10.0, 1.0, doubleGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 1.0, ba::clamp ( 0.0, 10.0, 1.0, doubleGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 10.0, 10.0, 1.0, doubleGreater ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.0, ba::clamp ( 11.0, 10.0, 1.0, doubleGreater ));
|
||||||
|
|
||||||
|
// Negative numbers
|
||||||
|
BOOST_CHECK_EQUAL ( -3.f, ba::clamp ( -3.f, -10.f, -1.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -1.f, ba::clamp ( -1.f, -10.f, -1.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -1.f, ba::clamp ( 0.f, -10.f, -1.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10.f, -1.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -11.f, -10.f, -1.f ));
|
||||||
|
|
||||||
|
// Mixed positive and negative numbers
|
||||||
|
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10.f, 10.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10.f, 10.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10.f, 10.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10.f, 10.f ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10.f, 10.f ));
|
||||||
|
|
||||||
|
// Mixed (1)
|
||||||
|
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10., 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10., 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10., 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10., 10. ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10., 10. ));
|
||||||
|
|
||||||
|
// Mixed (2)
|
||||||
|
BOOST_CHECK_EQUAL ( 5.f, ba::clamp ( 5.f, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -10.f, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( -10.f, ba::clamp ( -15.f, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 10.f, -10, 10 ));
|
||||||
|
BOOST_CHECK_EQUAL ( 10.f, ba::clamp ( 15.f, -10, 10 ));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_custom()
|
||||||
|
{
|
||||||
|
|
||||||
|
// Inside the range, equal to the endpoints, and outside the endpoints.
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 3), ba::clamp ( custom( 3), custom(1), custom(10)));
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 1), custom(1), custom(10)));
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 0), custom(1), custom(10)));
|
||||||
|
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(10), custom(1), custom(10)));
|
||||||
|
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(11), custom(1), custom(10)));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 3), ba::clamp ( custom( 3), custom(1), custom(10), customLess ));
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 1), custom(1), custom(10), customLess ));
|
||||||
|
BOOST_CHECK_EQUAL ( custom( 1), ba::clamp ( custom( 0), custom(1), custom(10), customLess ));
|
||||||
|
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(10), custom(1), custom(10), customLess ));
|
||||||
|
BOOST_CHECK_EQUAL ( custom(10), ba::clamp ( custom(11), custom(1), custom(10), customLess ));
|
||||||
|
|
||||||
|
// Fail!!
|
||||||
|
// BOOST_CHECK_EQUAL ( custom(1), ba::clamp ( custom(11), custom(1), custom(10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define elementsof(v) (sizeof (v) / sizeof (v[0]))
|
||||||
|
#define a_begin(v) (&v[0])
|
||||||
|
#define a_end(v) (v + elementsof (v))
|
||||||
|
#define a_range(v) v
|
||||||
|
#define b_e(v) a_begin(v),a_end(v)
|
||||||
|
|
||||||
|
void test_int_range ()
|
||||||
|
{
|
||||||
|
int inputs [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 99, 999, -1, -3, -99, 234234 };
|
||||||
|
int outputs [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, -1, -1, -1, 10 };
|
||||||
|
std::vector<int> results;
|
||||||
|
std::vector<int> in_v;
|
||||||
|
|
||||||
|
std::copy ( a_begin(inputs), a_end(inputs), std::back_inserter ( in_v ));
|
||||||
|
|
||||||
|
ba::clamp_range ( a_begin(inputs), a_end(inputs), std::back_inserter ( results ), -1, 10 );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
ba::clamp_range ( in_v.begin (), in_v.end (), std::back_inserter ( results ), -1, 10 );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
|
||||||
|
ba::clamp_range ( a_begin(inputs), a_end(inputs), std::back_inserter ( results ), 10, -1, intGreater );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
ba::clamp_range ( in_v.begin (), in_v.end (), std::back_inserter ( results ), 10, -1, intGreater );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
|
||||||
|
ba::clamp_range ( a_range(inputs), std::back_inserter ( results ), -1, 10 );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
ba::clamp_range ( in_v, std::back_inserter ( results ), -1, 10 );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
|
||||||
|
ba::clamp_range ( a_range(inputs), std::back_inserter ( results ), 10, -1, intGreater );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
ba::clamp_range ( in_v, std::back_inserter ( results ), 10, -1, intGreater );
|
||||||
|
BOOST_CHECK ( std::equal ( results.begin(), results.end (), outputs ));
|
||||||
|
results.clear ();
|
||||||
|
|
||||||
|
int junk[elementsof(inputs)];
|
||||||
|
ba::clamp_range ( inputs, junk, 10, -1, intGreater );
|
||||||
|
BOOST_CHECK ( std::equal ( b_e(junk), outputs ));
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_main( int , char* [] )
|
||||||
|
{
|
||||||
|
test_ints ();
|
||||||
|
test_floats ();
|
||||||
|
test_custom ();
|
||||||
|
|
||||||
|
test_int_range ();
|
||||||
|
// test_float_range ();
|
||||||
|
// test_custom_range ();
|
||||||
|
return 0;
|
||||||
|
}
|
83
test/empty_search_test.cpp
Executable file
83
test/empty_search_test.cpp
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||||
|
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/test_exec_monitor.hpp>
|
||||||
|
|
||||||
|
int test_main( int argc, char *argv [] )
|
||||||
|
{
|
||||||
|
const std::string cs;
|
||||||
|
std::string estr;
|
||||||
|
std::string str ( "abc" );
|
||||||
|
|
||||||
|
// empty corpus, empty pattern
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_search (
|
||||||
|
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||||
|
== cs.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_horspool_search (
|
||||||
|
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||||
|
== cs.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::knuth_morris_pratt_search (
|
||||||
|
cs.begin (), cs.end (), estr.begin (), estr.end ())
|
||||||
|
== cs.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
// empty corpus, non-empty pattern
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_search (
|
||||||
|
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||||
|
== estr.end ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_horspool_search (
|
||||||
|
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||||
|
== estr.end ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::knuth_morris_pratt_search (
|
||||||
|
estr.begin (), estr.end (), str.begin (), str.end ())
|
||||||
|
== estr.end ()
|
||||||
|
);
|
||||||
|
|
||||||
|
// non-empty corpus, empty pattern
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_search (
|
||||||
|
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||||
|
== str.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::boyer_moore_horspool_search (
|
||||||
|
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||||
|
== str.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOST_CHECK (
|
||||||
|
boost::algorithm::knuth_morris_pratt_search (
|
||||||
|
str.begin (), str.end (), estr.begin (), estr.end ())
|
||||||
|
== str.begin ()
|
||||||
|
);
|
||||||
|
|
||||||
|
(void) argv; (void) argc;
|
||||||
|
return 0;
|
||||||
|
}
|
26
test/search_fail1.cpp
Normal file
26
test/search_fail1.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
|
||||||
|
int main( int argc, char *argv [] )
|
||||||
|
{
|
||||||
|
std::vector<char> cv;
|
||||||
|
std::vector<int> iv;
|
||||||
|
|
||||||
|
// Should fail to compile because the underlying types are different
|
||||||
|
// They are (almost certainly) different sizes
|
||||||
|
(void) boost::algorithm::boyer_moore_search (
|
||||||
|
cv.begin (), cv.end (), iv.begin (), iv.end ());
|
||||||
|
|
||||||
|
|
||||||
|
(void) argv; (void) argc;
|
||||||
|
return 0;
|
||||||
|
}
|
27
test/search_fail2.cpp
Normal file
27
test/search_fail2.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
|
||||||
|
int main( int argc, char *argv [] )
|
||||||
|
{
|
||||||
|
std::vector<boost::uint8_t> cv;
|
||||||
|
std::vector<boost:: int8_t> iv;
|
||||||
|
|
||||||
|
// Should fail to compile because the underlying types are different
|
||||||
|
// They are the same size, but one is signed, and the other is not.
|
||||||
|
(void) boost::algorithm::boyer_moore_search (
|
||||||
|
cv.begin (), cv.end (), iv.begin (), iv.end ());
|
||||||
|
|
||||||
|
|
||||||
|
(void) argv; (void) argc;
|
||||||
|
return 0;
|
||||||
|
}
|
20
test/search_fail3.cpp
Normal file
20
test/search_fail3.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
|
||||||
|
int main( int argc, char *argv [] )
|
||||||
|
{
|
||||||
|
// Should fail to compile because the search objects are not default-constructible
|
||||||
|
boost::algorithm::boyer_moore<std::vector<char>::iterator> bm;
|
||||||
|
|
||||||
|
(void) argv; (void) argc;
|
||||||
|
return 0;
|
||||||
|
}
|
272
test/search_test1.cpp
Executable file
272
test/search_test1.cpp
Executable file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||||
|
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/test_exec_monitor.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace ba = boost::algorithm;
|
||||||
|
|
||||||
|
template <typename Iter>
|
||||||
|
std::string make_str ( Iter first, std::size_t len ) {
|
||||||
|
std::string retVal ( len + 2, '\'' );
|
||||||
|
std::copy ( first, first+len, retVal.begin () + 1);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Check using iterators
|
||||||
|
template<typename Container>
|
||||||
|
void check_one_iter ( const Container &haystack, const std::string &needle, int expected ) {
|
||||||
|
typedef typename Container::const_iterator iter_type;
|
||||||
|
typedef std::string::const_iterator pattern_type;
|
||||||
|
|
||||||
|
iter_type hBeg = haystack.begin ();
|
||||||
|
iter_type hEnd = haystack.end ();
|
||||||
|
pattern_type nBeg = needle.begin ();
|
||||||
|
pattern_type nEnd = needle.end ();
|
||||||
|
|
||||||
|
iter_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
iter_type it1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
iter_type it1r = ba::boyer_moore_search (haystack, nBeg, nEnd);
|
||||||
|
iter_type it2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
iter_type it3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
|
||||||
|
|
||||||
|
std::cout << "(Iterators) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||||
|
try {
|
||||||
|
if ( it0 != it1 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it1r ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between iterator and range boyer_moore search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it2 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it3 )
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( ... ) {
|
||||||
|
std::cout << "Searching for: " << needle << std::endl;
|
||||||
|
std::cout << "Expected: " << expected << "\n";
|
||||||
|
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
|
||||||
|
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
|
||||||
|
std::cout << " bm(r): " << std::distance ( hBeg, it1r ) << "\n";
|
||||||
|
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
|
||||||
|
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
|
||||||
|
std::cout << std::flush;
|
||||||
|
throw ;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( dist, expected );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check using pointers
|
||||||
|
// We're assuming that the container implements contiguous storage here.
|
||||||
|
template<typename Container>
|
||||||
|
void check_one_pointer ( const Container &haystack, const std::string &needle, int expected ) {
|
||||||
|
typedef const typename Container::value_type *ptr_type;
|
||||||
|
ptr_type hBeg = haystack.size () == 0 ? NULL : &*haystack.begin ();
|
||||||
|
ptr_type hEnd = hBeg + haystack.size ();
|
||||||
|
ptr_type nBeg = needle.size () == 0 ? NULL : &*needle.begin ();
|
||||||
|
ptr_type nEnd = nBeg + needle.size ();
|
||||||
|
|
||||||
|
ptr_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
ptr_type it1 = ba::boyer_moore_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
ptr_type it2 = ba::boyer_moore_horspool_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
ptr_type it3 = ba::knuth_morris_pratt_search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
|
||||||
|
|
||||||
|
std::cout << "(Pointers) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||||
|
try {
|
||||||
|
if ( it0 != it1 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it2 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it3 )
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( ... ) {
|
||||||
|
std::cout << "Searching for: " << needle << std::endl;
|
||||||
|
std::cout << "Expected: " << expected << "\n";
|
||||||
|
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
|
||||||
|
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
|
||||||
|
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
|
||||||
|
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
|
||||||
|
std::cout << std::flush;
|
||||||
|
throw ;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( dist, expected );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check using objects
|
||||||
|
template<typename Container>
|
||||||
|
void check_one_object ( const Container &haystack, const std::string &needle, int expected ) {
|
||||||
|
typedef typename Container::const_iterator iter_type;
|
||||||
|
typedef std::string::const_iterator pattern_type;
|
||||||
|
|
||||||
|
iter_type hBeg = haystack.begin ();
|
||||||
|
iter_type hEnd = haystack.end ();
|
||||||
|
pattern_type nBeg = needle.begin ();
|
||||||
|
pattern_type nEnd = needle.end ();
|
||||||
|
|
||||||
|
ba::boyer_moore<pattern_type> bm_r = ba::make_boyer_moore ( needle );
|
||||||
|
ba::boyer_moore<pattern_type> bm ( nBeg, nEnd );
|
||||||
|
ba::boyer_moore_horspool<pattern_type> bmh ( nBeg, nEnd );
|
||||||
|
ba::knuth_morris_pratt<pattern_type> kmp ( nBeg, nEnd );
|
||||||
|
|
||||||
|
iter_type it0 = std::search (hBeg, hEnd, nBeg, nEnd);
|
||||||
|
iter_type it1 = bm (hBeg, hEnd);
|
||||||
|
iter_type it1r = bm (haystack);
|
||||||
|
iter_type rt1 = bm_r (hBeg, hEnd);
|
||||||
|
iter_type rt1r = bm_r (haystack);
|
||||||
|
iter_type it2 = bmh (hBeg, hEnd);
|
||||||
|
iter_type it3 = kmp (hBeg, hEnd);
|
||||||
|
const int dist = it1 == hEnd ? -1 : std::distance ( hBeg, it1 );
|
||||||
|
|
||||||
|
std::cout << "(Objects) Pattern is " << needle.length () << ", haysstack is " << haystack.length () << " chars long; " << std::endl;
|
||||||
|
try {
|
||||||
|
if ( it0 != it1 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between std::search and boyer-moore search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it1r ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between iterator and range boyer_moore search(1)" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != rt1 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between iterator and range boyer_moore search(2)" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rt1 != rt1r ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between iterator and range boyer_moore search(3)" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it2 ) {
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and boyer-moore-horspool search" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( it1 != it3 )
|
||||||
|
throw std::runtime_error (
|
||||||
|
std::string ( "results mismatch between boyer-moore and knuth-morris-pratt search" ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
catch ( ... ) {
|
||||||
|
std::cout << "Searching for: " << needle << std::endl;
|
||||||
|
std::cout << "Expected: " << expected << "\n";
|
||||||
|
std::cout << " std: " << std::distance ( hBeg, it0 ) << "\n";
|
||||||
|
std::cout << " bm: " << std::distance ( hBeg, it1 ) << "\n";
|
||||||
|
std::cout << " bm(r1): " << std::distance ( hBeg, it1r ) << "\n";
|
||||||
|
std::cout << " bm(r2): " << std::distance ( hBeg, rt1 ) << "\n";
|
||||||
|
std::cout << " bm(r3): " << std::distance ( hBeg, rt1r ) << "\n";
|
||||||
|
std::cout << " bmh: " << std::distance ( hBeg, it2 ) << "\n";
|
||||||
|
std::cout << " kpm: " << std::distance ( hBeg, it3 )<< "\n";
|
||||||
|
std::cout << std::flush;
|
||||||
|
throw ;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL ( dist, expected );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
void check_one ( const Container &haystack, const std::string &needle, int expected ) {
|
||||||
|
check_one_iter ( haystack, needle, expected );
|
||||||
|
check_one_pointer ( haystack, needle, expected );
|
||||||
|
check_one_object ( haystack, needle, expected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test_main( int , char* [] )
|
||||||
|
{
|
||||||
|
std::string haystack1 ( "NOW AN FOWE\220ER ANNMAN THE ANPANMANEND" );
|
||||||
|
std::string needle1 ( "ANPANMAN" );
|
||||||
|
std::string needle2 ( "MAN THE" );
|
||||||
|
std::string needle3 ( "WE\220ER" );
|
||||||
|
std::string needle4 ( "NOW " ); // At the beginning
|
||||||
|
std::string needle5 ( "NEND" ); // At the end
|
||||||
|
std::string needle6 ( "NOT FOUND" ); // Nowhere
|
||||||
|
std::string needle7 ( "NOT FO\340ND" ); // Nowhere
|
||||||
|
|
||||||
|
std::string haystack2 ( "ABC ABCDAB ABCDABCDABDE" );
|
||||||
|
std::string needle11 ( "ABCDABD" );
|
||||||
|
|
||||||
|
std::string haystack3 ( "abra abracad abracadabra" );
|
||||||
|
std::string needle12 ( "abracadabra" );
|
||||||
|
|
||||||
|
std::string needle13 ( "" );
|
||||||
|
std::string haystack4 ( "" );
|
||||||
|
|
||||||
|
check_one ( haystack1, needle1, 26 );
|
||||||
|
check_one ( haystack1, needle2, 18 );
|
||||||
|
check_one ( haystack1, needle3, 9 );
|
||||||
|
check_one ( haystack1, needle4, 0 );
|
||||||
|
check_one ( haystack1, needle5, 33 );
|
||||||
|
check_one ( haystack1, needle6, -1 );
|
||||||
|
check_one ( haystack1, needle7, -1 );
|
||||||
|
|
||||||
|
check_one ( needle1, haystack1, -1 ); // cant find long pattern in short corpus
|
||||||
|
check_one ( haystack1, haystack1, 0 ); // find something in itself
|
||||||
|
check_one ( haystack2, haystack2, 0 ); // find something in itself
|
||||||
|
|
||||||
|
check_one ( haystack2, needle11, 15 );
|
||||||
|
check_one ( haystack3, needle12, 13 );
|
||||||
|
|
||||||
|
check_one ( haystack1, needle13, 0 ); // find the empty string
|
||||||
|
check_one ( haystack4, needle1, -1 ); // can't find in an empty haystack
|
||||||
|
|
||||||
|
// Mikhail Levin <svarneticist@gmail.com> found a problem, and this was the test
|
||||||
|
// that triggered it.
|
||||||
|
|
||||||
|
const std::string mikhail_pattern =
|
||||||
|
"GATACACCTACCTTCACCAGTTACTCTATGCACTAGGTGCGCCAGGCCCATGCACAAGGGCTTGAGTGGATGGGAAGGA"
|
||||||
|
"TGTGCCCTAGTGATGGCAGCATAAGCTACGCAGAGAAGTTCCAGGGCAGAGTCACCATGACCAGGGACACATCCACGAG"
|
||||||
|
"CACAGCCTACATGGAGCTGAGCAGCCTGAGATCTGAAGACACGGCCATGTATTACTGTGGGAGAGATGTCTGGAGTGGT"
|
||||||
|
"TATTATTGCCCCGGTAATATTACTACTACTACTACTACATGGACGTCTGGGGCAAAGGGACCACG"
|
||||||
|
;
|
||||||
|
const std::string mikhail_corpus = std::string (8, 'a') + mikhail_pattern;
|
||||||
|
|
||||||
|
check_one ( mikhail_corpus, mikhail_pattern, 8 );
|
||||||
|
return 0;
|
||||||
|
}
|
145
test/search_test2.cpp
Executable file
145
test/search_test2.cpp
Executable file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||||
|
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/test_exec_monitor.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
typedef std::vector<char> vec;
|
||||||
|
#define NUM_TRIES 100
|
||||||
|
|
||||||
|
#define runOne(call, refDiff) { \
|
||||||
|
std::clock_t bTime, eTime; \
|
||||||
|
bTime = std::clock (); \
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) { \
|
||||||
|
res = boost::algorithm::call \
|
||||||
|
( haystack.begin (), haystack.end (), \
|
||||||
|
needle.begin (), needle.end ()); \
|
||||||
|
if ( res != exp ) { \
|
||||||
|
std::cout << "On run # " << i << " expected " \
|
||||||
|
<< exp - haystack.begin () << " got " \
|
||||||
|
<< res - haystack.begin () << std::endl; \
|
||||||
|
throw std::runtime_error \
|
||||||
|
( "Unexpected result from " #call ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
eTime = std::clock (); \
|
||||||
|
printRes ( #call, eTime - bTime, refDiff ); }
|
||||||
|
|
||||||
|
#define runObject(obj, refDiff) { \
|
||||||
|
std::clock_t bTime, eTime; \
|
||||||
|
bTime = std::clock (); \
|
||||||
|
boost::algorithm::obj <vec::const_iterator> \
|
||||||
|
s_o ( needle.begin (), needle.end ()); \
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) { \
|
||||||
|
res = s_o ( haystack.begin (), haystack.end ()); \
|
||||||
|
if ( res != exp ) { \
|
||||||
|
std::cout << "On run # " << i << " expected " \
|
||||||
|
<< exp - haystack.begin () << " got " \
|
||||||
|
<< res - haystack.begin () << std::endl; \
|
||||||
|
throw std::runtime_error \
|
||||||
|
( "Unexpected result from " #obj " object" ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
eTime = std::clock (); \
|
||||||
|
printRes ( #obj " object", eTime - bTime, refDiff ); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
vec ReadFromFile ( const char *name ) {
|
||||||
|
std::ifstream in ( name, std::ios_base::binary | std::ios_base::in );
|
||||||
|
vec retVal;
|
||||||
|
std::istream_iterator<char, char> begin(in);
|
||||||
|
std::istream_iterator<char, char> end;
|
||||||
|
|
||||||
|
std::copy ( begin, end, std::back_inserter ( retVal ));
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printRes ( const char *prompt, unsigned long diff, unsigned long stdDiff ) {
|
||||||
|
std::cout
|
||||||
|
<< std::setw(34) << prompt << " "
|
||||||
|
<< std::setw(6) << ( 1.0 * diff) / CLOCKS_PER_SEC << " seconds\t"
|
||||||
|
<< std::setw(5) << (100.0 * diff) / stdDiff << "% \t"
|
||||||
|
<< std::setw(12) << diff;
|
||||||
|
if ( diff > stdDiff )
|
||||||
|
std::cout << " !!";
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_one ( const vec &haystack, const vec &needle, int expected ) {
|
||||||
|
std::size_t i;
|
||||||
|
std::clock_t sTime;
|
||||||
|
unsigned long stdDiff;
|
||||||
|
|
||||||
|
vec::const_iterator res;
|
||||||
|
vec::const_iterator exp; // the expected result
|
||||||
|
|
||||||
|
if ( expected >= 0 )
|
||||||
|
exp = haystack.begin () + expected;
|
||||||
|
else if ( expected == -1 )
|
||||||
|
exp = haystack.end (); // we didn't find it!
|
||||||
|
else if ( expected == -2 )
|
||||||
|
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||||
|
else
|
||||||
|
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
|
||||||
|
|
||||||
|
std::cout << "Pattern is " << needle.size () << " entries long" << std::endl;
|
||||||
|
std::cout << "Corpus is " << haystack.size () << " entries long" << std::endl;
|
||||||
|
|
||||||
|
// First, the std library search
|
||||||
|
sTime = std::clock ();
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) {
|
||||||
|
res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||||
|
if ( res != exp ) {
|
||||||
|
std::cout << "On run # " << i << " expected " << exp - haystack.begin () << " got " << res - haystack.begin () << std::endl;
|
||||||
|
throw std::runtime_error ( "Unexpected result from std::search" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stdDiff = std::clock () - sTime;
|
||||||
|
printRes ( "std::search", stdDiff, stdDiff );
|
||||||
|
|
||||||
|
runOne ( boyer_moore_search, stdDiff );
|
||||||
|
runObject ( boyer_moore, stdDiff );
|
||||||
|
runOne ( boyer_moore_horspool_search, stdDiff );
|
||||||
|
runObject ( boyer_moore_horspool, stdDiff );
|
||||||
|
runOne ( knuth_morris_pratt_search, stdDiff );
|
||||||
|
runObject ( knuth_morris_pratt, stdDiff );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_main( int , char* [] )
|
||||||
|
{
|
||||||
|
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
|
||||||
|
vec p1b = ReadFromFile ( "search_test_data/0001b.pat" );
|
||||||
|
vec p1e = ReadFromFile ( "search_test_data/0001e.pat" );
|
||||||
|
vec p1n = ReadFromFile ( "search_test_data/0001n.pat" );
|
||||||
|
vec p1f = ReadFromFile ( "search_test_data/0001f.pat" );
|
||||||
|
|
||||||
|
std::cout << std::ios::fixed << std::setprecision(4);
|
||||||
|
// std::cout << "Corpus is " << c1.size () << " entries long\n";
|
||||||
|
std::cout << "--- Beginning ---" << std::endl;
|
||||||
|
check_one ( c1, p1b, 0 ); // Find it at position zero
|
||||||
|
std::cout << "---- Middle -----" << std::endl;
|
||||||
|
check_one ( c1, p1f, -2 ); // Don't know answer
|
||||||
|
std::cout << "------ End ------" << std::endl;
|
||||||
|
check_one ( c1, p1e, c1.size() - p1e.size ());
|
||||||
|
std::cout << "--- Not found ---" << std::endl;
|
||||||
|
check_one ( c1, p1n, -1 ); // Not found
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
145
test/search_test3.cpp
Executable file
145
test/search_test3.cpp
Executable file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2010-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||||
|
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||||
|
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/included/test_exec_monitor.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
typedef std::vector<std::string> vec;
|
||||||
|
#define NUM_TRIES 100
|
||||||
|
|
||||||
|
#define runOne(call, refDiff) { \
|
||||||
|
std::clock_t bTime, eTime; \
|
||||||
|
bTime = std::clock (); \
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) { \
|
||||||
|
res = boost::algorithm::call \
|
||||||
|
( haystack.begin (), haystack.end (), \
|
||||||
|
needle.begin (), needle.end ()); \
|
||||||
|
if ( res != exp ) { \
|
||||||
|
std::cout << "On run # " << i << " expected " \
|
||||||
|
<< exp - haystack.begin () << " got " \
|
||||||
|
<< res - haystack.begin () << std::endl; \
|
||||||
|
throw std::runtime_error \
|
||||||
|
( "Unexpected result from " #call ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
eTime = std::clock (); \
|
||||||
|
printRes ( #call, eTime - bTime, refDiff ); }
|
||||||
|
|
||||||
|
#define runObject(obj, refDiff) { \
|
||||||
|
std::clock_t bTime, eTime; \
|
||||||
|
bTime = std::clock (); \
|
||||||
|
boost::algorithm::obj <vec::const_iterator> \
|
||||||
|
s_o ( needle.begin (), needle.end ()); \
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) { \
|
||||||
|
res = s_o ( haystack.begin (), haystack.end ()); \
|
||||||
|
if ( res != exp ) { \
|
||||||
|
std::cout << "On run # " << i << " expected " \
|
||||||
|
<< exp - haystack.begin () << " got " \
|
||||||
|
<< res - haystack.begin () << std::endl; \
|
||||||
|
throw std::runtime_error \
|
||||||
|
( "Unexpected result from " #obj " object" ); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
eTime = std::clock (); \
|
||||||
|
printRes ( #obj " object", eTime - bTime, refDiff ); }
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
vec ReadFromFile ( const char *name ) {
|
||||||
|
std::ifstream in ( name, std::ios_base::binary | std::ios_base::in );
|
||||||
|
std::string temp;
|
||||||
|
vec retVal;
|
||||||
|
while ( std::getline ( in, temp ))
|
||||||
|
retVal.push_back ( temp );
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printRes ( const char *prompt, unsigned long diff, unsigned long stdDiff ) {
|
||||||
|
std::cout
|
||||||
|
<< std::setw(34) << prompt << " "
|
||||||
|
<< std::setw(6) << ( 1.0 * diff) / CLOCKS_PER_SEC << " seconds\t"
|
||||||
|
<< std::setw(5) << (100.0 * diff) / stdDiff << "% \t"
|
||||||
|
<< std::setw(12) << diff;
|
||||||
|
if ( diff > stdDiff )
|
||||||
|
std::cout << " !!";
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_one ( const vec &haystack, const vec &needle, int expected ) {
|
||||||
|
std::size_t i;
|
||||||
|
std::clock_t sTime;
|
||||||
|
unsigned long stdDiff;
|
||||||
|
|
||||||
|
vec::const_iterator res;
|
||||||
|
vec::const_iterator exp; // the expected result
|
||||||
|
|
||||||
|
if ( expected >= 0 )
|
||||||
|
exp = haystack.begin () + expected;
|
||||||
|
else if ( expected == -1 )
|
||||||
|
exp = haystack.end (); // we didn't find it1
|
||||||
|
else if ( expected == -2 )
|
||||||
|
exp = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||||
|
else
|
||||||
|
throw std::logic_error ( "Expected must be -2, -1, or >= 0" );
|
||||||
|
|
||||||
|
std::cout << "Pattern is " << needle.size () << " entries long" << std::endl;
|
||||||
|
std::cout << "Corpus is " << haystack.size () << " entries long" << std::endl;
|
||||||
|
|
||||||
|
// First, the std library search
|
||||||
|
sTime = std::clock ();
|
||||||
|
for ( i = 0; i < NUM_TRIES; ++i ) {
|
||||||
|
res = std::search ( haystack.begin (), haystack.end (), needle.begin (), needle.end ());
|
||||||
|
if ( res != exp ) {
|
||||||
|
std::cout << "On run # " << i << " expected " << exp - haystack.begin () << " got " << res - haystack.begin () << std::endl;
|
||||||
|
throw std::runtime_error ( "Unexpected result from std::search" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stdDiff = std::clock () - sTime;
|
||||||
|
printRes ( "std::search", stdDiff, stdDiff );
|
||||||
|
|
||||||
|
runOne ( boyer_moore_search, stdDiff );
|
||||||
|
runObject ( boyer_moore, stdDiff );
|
||||||
|
runOne ( boyer_moore_horspool_search, stdDiff );
|
||||||
|
runObject ( boyer_moore_horspool, stdDiff );
|
||||||
|
runOne ( knuth_morris_pratt_search, stdDiff );
|
||||||
|
runObject ( knuth_morris_pratt, stdDiff );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_main( int , char* [] )
|
||||||
|
{
|
||||||
|
vec c1 = ReadFromFile ( "search_test_data/0001.corpus" );
|
||||||
|
vec p1b = ReadFromFile ( "search_test_data/0002b.pat" );
|
||||||
|
vec p1e = ReadFromFile ( "search_test_data/0002e.pat" );
|
||||||
|
vec p1n = ReadFromFile ( "search_test_data/0002n.pat" );
|
||||||
|
vec p1f = ReadFromFile ( "search_test_data/0002f.pat" );
|
||||||
|
|
||||||
|
std::cout << std::ios::fixed << std::setprecision(4);
|
||||||
|
// std::cout << "Corpus is " << c1.size () << " entries long\n";
|
||||||
|
std::cout << "--- Beginning ---" << std::endl;
|
||||||
|
check_one ( c1, p1b, 0 ); // Find it at position zero
|
||||||
|
std::cout << "---- Middle -----" << std::endl;
|
||||||
|
check_one ( c1, p1f, -2 ); // Don't know answer
|
||||||
|
std::cout << "------ End ------" << std::endl;
|
||||||
|
check_one ( c1, p1e, c1.size() - p1e.size ());
|
||||||
|
std::cout << "--- Not found ---" << std::endl;
|
||||||
|
check_one ( c1, p1n, -1 ); // Not found
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
43067
test/search_test_data/0001.corpus
Normal file
43067
test/search_test_data/0001.corpus
Normal file
File diff suppressed because it is too large
Load Diff
2
test/search_test_data/0001b.pat
Normal file
2
test/search_test_data/0001b.pat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
TU0AKgAfhPqScHN4dnZ2e3p5e3h7eXl4dnd1dnV3enp5dnd3dHV1dHNzd3l3eHh5
|
||||||
|
eXZ4dXd2dHNwcHFwcXBxc3h0dHN1eHVzcXV1dXV2c3h5dHV3eHVwcHF
|
2
test/search_test_data/0001e.pat
Normal file
2
test/search_test_data/0001e.pat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
iBJbmMuLCBhbGwg
|
||||||
|
cmlnaHRzIHJlc2VydmVkLgAAAAA=
|
2
test/search_test_data/0001f.pat
Normal file
2
test/search_test_data/0001f.pat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
q/y9PZ3uHj5ufo6UJDQ0NFQz8+RUZBQEBAOzo6Ozs4Nz06Ojs4Ojo9PT47Ojk0
|
||||||
|
Nzc7OjQ6NzU6OjgxMzg1OjY2NjU3NTU1Nzc3NTU1NzU
|
2
test/search_test_data/0001n.pat
Normal file
2
test/search_test_data/0001n.pat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
TIzMjIyMjM0MjM1nTQzNTc3MzY1NDU2NzQ2MjEwMjU1MTQ2NzU0NDI1
|
||||||
|
NDMyMzQxMzQ0NDU1MjU2NTc5NzU1NDc4ODY1
|
170
test/search_test_data/0002b.pat
Normal file
170
test/search_test_data/0002b.pat
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
TU0AKgAfhPqScHN4dnZ2e3p5e3h7eXl4dnd1dnV3enp5dnd3dHV1dHNzd3l3eHh5
|
||||||
|
eXZ4dXd2dHNwcHFwcXBxc3h0dHN1eHVzcXV1dXV2c3h5dHV3eHVwcHF1d3V0dXJy
|
||||||
|
cXNzcHBwcHJyc3R0dXl7eHJycnF1dHV2d3h4eHV0cnRycXN1dXN0c3R0c3R0cXJx
|
||||||
|
cHNxb3B0c29scHFybm9sbGpscXJ1c3NycXN0cHFvb3JzdHBycG9vb29vb29ubXBt
|
||||||
|
bG9vcW5tbGptb3Fwb3Bwb25vbXFtbGtvbGlrbnBuamxsbW1rbW1vbm1ub3Btamxw
|
||||||
|
bWpsbG9xcG5ua2tpamhqZ2hnam5saWhsbG1nZmZnZ2lnamtxa2ppZWZmZWlrZ2hp
|
||||||
|
Z2hraWRmZ2psa2pmZWVkZmplZWZiYF1gZGVlYmJiY2RhY2NiYVxdW1xgXl9iZV9d
|
||||||
|
X11hXF5gZWJhYF5dXWFmYl9hXl5gXmBhZGFhYV1cYWFiX2FgXFxgYF5iYmNiYWRk
|
||||||
|
YWFjYGFgXl9jYmVlZGZiYV1cXFtbW1pYV1dVV1VWVlFQT1FRUVBRTkxLSktNTVFP
|
||||||
|
UU1RUVBSUlBPUlNTUVRWWFpcVldXWldXVVhYVlpbWV1dX1tbW11fYWFdXV5iY2Rg
|
||||||
|
YFxeYmNmZGJgYFxdYmdjYWFhYGJoZGReXF9gX2BhYWJhXltdXVtaXGJlYV5gYF9f
|
||||||
|
XVxcX2JiYWJkZmNjZGNhYmFcW15dXmBgX1xdYF5fXF5eX15bWV1dXl9eWlldXGJf
|
||||||
|
XmFgXVpcXF1dXlpdXl9dXWRlYF5cXFtfYF1eYl1hX1xbXV1ZV1hZWltbW1peW1lb
|
||||||
|
XlteW1xeXlxbXVpYW11dY19fW1xfX2NhXV5hZWNfX2FjZGJlZmVoaWtlY2FkXl5f
|
||||||
|
YWJjX19fX15dXWBjYmJeWlteXVlaXmBeXF1fXVxdXFtaW19dXFtfWllZWVxeXlxb
|
||||||
|
XV9eW1xcXF5cW1paVVdbWVteW1pbWlZeYV1ZV1tYVlVWV1hbWVhcWVhVWlhbWFtX
|
||||||
|
V1ZWWFtXVlZaVlRVVVdVVldWVlNRU1NTUVNXVVlZWVZVVFNWVlRTU1JVV1ZWVFRU
|
||||||
|
UVFVWVpZWlZWWFpYWllcXVpYWFdWWFxbWFlYWVhVVVRVV1dZWllYV1lcXVpcWVhY
|
||||||
|
V1VbW1tVVVdaXFpXVlZZW1leW1lWWFdaXVpXWlZXW1xdXFxgX1xYXVxcXFhaW1tb
|
||||||
|
WlxcWltdWldXVldXWVZVUVJVWFlcW1tcWVpgXF9hX11aWVpdXFxeXFtbX19aW1lb
|
||||||
|
W1paWlxdXVpaXVxeX1xdX2JjYV9gYl9cW1xbWFpeXl1gYGBgYFtdY2JhYmBgYGBe
|
||||||
|
YGJkY2NjYmNjYGNiY2JgX19hYV1gX2BgX19hZWRiZWJjZWVgYmFiZGRmaWdmYWJj
|
||||||
|
YmJjZGFhY2FhY2RkZmVmY2FhYWVnaWVjZGNhY2RlZWZqZ2doZ2RjZGRmaGVlZmZm
|
||||||
|
Z2dnaGhoZ2hmY2VmZWZjZWNlaWdlZmVoZ2hpamlra2hram1samtqZWpuc2tpa21u
|
||||||
|
bmtraWtqYWNmZmZmZGVpZ2p0kMLk8vv+/////////5drcHZ1dnd7fHt6end0c3V1
|
||||||
|
dnR0d3l3d3Z3fH16dnV2d3h0d3l2d3h4dXZ3d3d3dnBucW5vb3BxdHR3d3Jzd3Vz
|
||||||
|
dndzc3V6eHVyc3JydXZxc3Z1d3V0eHZ1c3Bvc3V0dnR0dXR0dHd4dnRxc3J0c3d3
|
||||||
|
dXNycXd1dnVzcHJ0d3h0dHFwcXFzc3N0dXFxcXFwcHFwcnFycHJwcHJzc3Fwc3Nx
|
||||||
|
cnRyc29ucHJ0cnBwb29ub3Fwc3R0cnJubnBycG1ucHBxcXBuc3FwbGpoamlsb3By
|
||||||
|
c25qaW1tcW1qbXFua25xb21vcG9tbG5qa2doaW1sbGpqamxsaWpmZ2VlZ2tqZ2Zn
|
||||||
|
amVoa2tvZ2ttamxpamlmZmdoZ2dnZ2traWZmaGlpa2loaGdmZ2ZoZmRnZ2ZmZ2Vl
|
||||||
|
ZmJiZWBhYmBhZGBhX2BfXVxfYmJkZF5dY2JjYWNhY2BgXl5gXl5dXl5cXFxgZGVh
|
||||||
|
Xl5eXlxeXl5iYl9fYF9iYWFhZWRkY2RgX2BhX19gY2VlZWRkZF1gYV9bWV1dWVxX
|
||||||
|
WldXVlZVU1BQUE5QUU9SUU5NUE9OTk9NT1FRUk5PUVRUUVJSVFVYWVpXVldVVlRV
|
||||||
|
V1dZXl9bW1pYWVhaXl9gXl5bYGJhYWFhX19jZGZmZGJgYF9eX19fYWRmX2RgYWBe
|
||||||
|
XmFhYWNhYmBeXV5eW1xdYF5dX2NiX19hX11dYmVoY2RlZWFeYF5fXV5hYGFgYF9i
|
||||||
|
Y19dXl5dYGNgXFZbXlxZWVxhYl5gYF9cXV1cXFxdX19gYVxZW11dX2NjXF5eXF5e
|
||||||
|
Xl9eYGJfXl9eW1xcX11ZW1xdW15eW11gXl1dW11cX15dXl1cXF5iX2BgYV9iYmJf
|
||||||
|
XF1mY2NiamZiYWNiY2JiYmVpbGdkYGBmY2VoY11dXFxcX15iYmFiYmBeW19hX19h
|
||||||
|
XV5aYlxZWlxcW1xcW2BfW1hZXF5cXVtcXlxbWldYW1xcXVpYWFlYWllbW1paWFpe
|
||||||
|
XFtYWFdUU1ZVWFhVWFteWFdYW1pYVlhVU1RVWVZXVVdXVVFSU1ZWVFNSVVtSUlJT
|
||||||
|
UlNUVVVWVVVWVVJWVVVTVldXXFlXVVlbVVNUWVtXWVtVVVZVWltZWltYVVVZWVlY
|
||||||
|
V1ZXWVVUV1dXWl1dW1tcX1lZWl5cXVtcWVVXXFxZXVxZVVRUWVlcWVZWWFhaWFtd
|
||||||
|
WV5YVlZZWVxbXFxdXFtbXl5dXVtbWV5dYF9cXl9eXF9iXl5bWlhbWltZWFpgXlpa
|
||||||
|
W15iXF1jYVtcYGBfXVpbXFxcWlxbXFtZXFxaWllaXl1aW11gXV5fX19fX19hXl5f
|
||||||
|
YGFgYWBhXmBiXlxfXFtcXmBgYmJkYWJgYmNgYGJiYWBfX19jZWBeYWJgYFxcY2Vj
|
||||||
|
ZGJfX2JiYWNmY2RjYmFhYWFjYWNpZmNjZ2ZkZGBiYmVmZ2VjYmNlZV9iZWhlZWJi
|
||||||
|
Y2JmZWdoZWVoZmdrZ2VmZmhmZGRkZ2VmZmVkZmppZmVnaGhqamhiZmZnaWdnamZm
|
||||||
|
ZmtubGtpZWhna21rZmRpaWVlZ2l0bGtrbG1obmdmamZnaGVkZGNobYekwePx+///
|
||||||
|
////////l2pzdnh3fHt8enp5fnl2d3Vyc3d5eXd1d3d3eXx+eHp3eHR0d3d6enl1
|
||||||
|
dHNzc3d1dXNwcHJ0c3Byc3V3eXVycnZ5enl3dnh3dnJxdHZ3dXh8eHl1dXZ3dnZ1
|
||||||
|
dHV0ent2dXl3dXV1d3h3dnZ3enV0d3d0dXN3dXZ1dnd3d3h6eHZzc3JwcnN0dHJy
|
||||||
|
cXFub3FycW9vcHBvbGxsbXFzcHF1c3N0dHR0c3Bvc3N1cnFvcW9tbXFzcm5ub3Bw
|
||||||
|
b21ucXBxcXBvc3Bvbm5sa25sbW1vbnJ0b2trbWpqbGtsbnFxcG9vbm1xbm5tbGpp
|
||||||
|
amtqbm1rbW9sa21taWhoZmlqaGlramxqaWdraGdqaWluam9ua2psamhkZmxpaWpq
|
||||||
|
aWVlZWdnaGZjY2RpZmZnZmZmZ2ZnZGFhZWNgZGJhY11dXV5hXF9lZGRiY2JhYV5f
|
||||||
|
YGZgYF5fYWJgYmBgX15gZF9eYF1gYlxeYV5fYV5eYF5gYWJkX2JhZGNlZGJjYmFh
|
||||||
|
YWNgY2VhZGZkY2JgYWBjY15fXFtaWllaXFlYVlNRUVNTUU5PUlNSVlRPU09PUVJS
|
||||||
|
U1FNT1JVUk9RU1NRU1NSVFRWVllWWFtXWFhaWlpeXl1hYV9cXV5fXl9gXmFgYGBh
|
||||||
|
ZmJjYmJjYV9fX19dYWFiZmRiYWBeX2FcW15fYWBfXmNkX11cXF1cXVxfYl9hYWJd
|
||||||
|
X2BhY2JjX2BkZGFgYWFfYWFgYF9eX2JiZGVjY19dYF9eXV1eXF9hXmBeXF1fXV9b
|
||||||
|
XGFhY2FkX11dW1peXl9hYWJgX19jYV5dYGFgYGBdWV5cXV9hYGBcX2BhYF5gZWBb
|
||||||
|
X19dXWBeXl1eYWNhXl1eYGFhYGFgYWFhZGNiZGZoZWdnZWNgXWFhX2NlY2NjYGBl
|
||||||
|
Y2NjY11bXl9eXmBiYGFgXF9kYF5iYF9iYl9cW15aWV5fXFtaWVpdW1xfYGBfXV5d
|
||||||
|
XFtcWlhXVlZWWFhYV1ZWV1daWlhbWlpcXFhaWFdYVldYWFlZWWFYWltYWVhSVFdV
|
||||||
|
VlpWV1RYV1VTVFRYVVRWU1RUVVhWVVRUVFZXVFVXV1VWV1ZYV1lcbltbWV5ZWlpX
|
||||||
|
V1VSWFtfW1laXV5bWFpZWlpYWVhYW1hYV1daWVlZV15dWlxgXVpZWV1hXFpbW1dY
|
||||||
|
WlpZVldXWlpWVlZXWlhaWVlZWVpZW1xbWltcWVhaXVxdWVxZWVtaX2BfXFlaWVte
|
||||||
|
XV5dXV9eXF9bW1xbXl9hXFdcXlxbWVpbXFpcWF1gXV9gYF9aW11cX15dX19gXFtY
|
||||||
|
WVtZW1tdXWBiYWBfXV5cXV5dX15eXV1iZWRhYWFiYF9eYmBeXV5dYWBdXWBlY2Fh
|
||||||
|
YWRfYF9hY2RhZGJjZGZjYmJfYV5fZGJkYWBgYGBjY2RlaGNhY2BjYF9eYWJgY2Vk
|
||||||
|
Y2JlZWRhYmRlY2FjY2RjY2RjY2NjYWBkY2NjZGVjYWRnaGhramtqZmdnZmhoZ2pn
|
||||||
|
aGhoZmhpa2lpaGhoZ2hlZmdqaGZsbWhpamlqamppa21qaGhmaGxqZWVra25sbW5p
|
||||||
|
aWhraWprbW1pZ2ZoZ2hsfKXG4/D7//////////+UbnR5e3t6eHmAfH58eHZ2dHd2
|
||||||
|
d3x3dHZ2dnl4eHt8fHh4dXVydXR3eXd2dXR4d3Z1dXZ1dnhydHd5d3ZzdHV4dXR2
|
||||||
|
eX13dnV2dHN1eXh4eHd3dnd2d3Z3dXZ3dXZ3eXh5dnR4eHV2eHt8e3l1d3d1dndz
|
||||||
|
dXV2d3Z1eHh0dXR2d3V0dnNxcXFvb29yc3FucnJycW9ycnBvbG5ycXF0cnNyc3Nz
|
||||||
|
cnFydHFvcHFycnNucXJvb3FzcHBxc3NxcG1ucG9wb3NxcXJwa2xtbXFwbnJtbnFv
|
||||||
|
b25uamtqbG1scHJwa25tbXBycG9tbW5vbnBvb2xtb2xxbmtsbGtpamtrbGtnamlq
|
||||||
|
a2pnaGhmZmptaGhoaGxqaGhpaGhpaWlpZmVkZWdoZ2lmY2RgYmhmamdlamdhYWNg
|
||||||
|
X2BgYmNhYV1eYWFmZGRkZF9cXWBgX19fY2NdYWFiYWJhXl5kYWJhXF5eX19hYmZi
|
||||||
|
Xl1gYmJiYV5iY2FhYmRhX2BlYWFiY2FfYWJhYmRjZGJeYmNmZGBhYmFaWVpaXFtZ
|
||||||
|
V1ZUU1NSVVVXWVNSUE5NT1JPTk1NT09OUlVOTk1PU1NRU1JTVFRRU1NWV1dXWlhb
|
||||||
|
W19bX11cX15fXFpeXV1dXV9fX15hYGBhZWJhX2FhYGBeXmFmZmJhYV9fYWFeXl1b
|
||||||
|
XFxcXWJgYGFgXV5eW1peX2BgYF5iY2RiYV9gYmFhX2BhYmNiYWBhYWJfYWFfYF1f
|
||||||
|
YWBgY19fXV5kYVlcX2FgYF1eW11gX15dXGBgX11hXltbW1teX2FdX15cW11cXF1e
|
||||||
|
X2BfYGRmW1tfYFxeYWNiX15dXmBcXF5gX2RfW2BjYmFhY19bWl9hXl9hYmBeYWVk
|
||||||
|
YmRiYmNjY2NjY2FjZGNgZGJjYmBfX19eYmJeXl1eXF5gXV1dXV1cXFtbW15fXV1e
|
||||||
|
XlxdW1xeXmBbWVpYVltgYF5dXV1eWVlbW1xZVlZVWFhcXl1aWllWWllbXVxbWFha
|
||||||
|
WFpbW1lZVldXVVZdV1daW1hYV1hVV1hTV1VUWFlXVVNVVVJSVVVWVlJWVlZWVFRW
|
||||||
|
U1VVUlVUV1RWUlJYVldXVFdcXVlYV1JQVVlTVVZXV1ZTU1dYV1VUWV5bV1RWV1pY
|
||||||
|
WFlbWldZWlpaWFdZXVlcXlpcXFlcWltfW1hZWltZXVteWFRSV1hZWlpZWFhXWFla
|
||||||
|
WFheWVtZV1laW1tcWFlcXF1eXVtYWlpbXF1dX1xbWltcXl5hYVtZWl5ZWVxeXV5d
|
||||||
|
XltaVlhaWVxcW1pbXV5eXlxdXV9eWllbW1tfXlxeXWBeXGFeXl5gX2BfXlxgY2Ji
|
||||||
|
YWFhZWJgXWBfYV9dXl1cX2BeXl9eXFtcX19gX15hY2NgY2NnZWFjY2FkZGJjZGJi
|
||||||
|
Y2BhYmNkY2NhYWJjZWJiYGJkY2BhZWVmYmRkZmVmZGNiX2FkZGNkZGJjZWRlZGJi
|
||||||
|
YmRjYmhjYGJmaGlmY2NnZWhlaWtramhmZmZqZGhpaGZnZmRnaGloZGhqbW9tamdp
|
||||||
|
bGtubGlsbmxpbW9wbGtra3ZoZGdpamhnZmhpaGhtbW1ra21qaGt+psnk8Pr+////
|
||||||
|
/////3ZnbnV6fHh2eHp7fHx6d3h3dXV6eHd5dXNzc3h5eXl1d3d3d3h2dnd0dXR0
|
||||||
|
d3h5eXh6dnV1cXR1dHV1dHR2d3h3d3p4enp5c3Z3dXV0dXl4dXV4eXt5dnZ0dnp5
|
||||||
|
eHZ4dnd1dnNzdHJ4fHx8eX16eXh2dnR0dHV2eHV0eXRycnB0cnNwc3dzb3FvcXNv
|
||||||
|
b3Fyc3Bxc3JwbmxucXJycnRzcXBwdHV1dnVzdHJvcnFycnZxcXFxcXJwb3BvcXRw
|
||||||
|
bXFvbXBubGpwcXFtbG5ub25xcW9rbG1tbGxta2xrcnRxcm5qaWxra25wb3Byc3Zw
|
||||||
|
b2xsbWtub21ra2xpam5tbG9ybGxrampramlpbHVza21maGxqaGhnaWxrbHBsa2tp
|
||||||
|
amhnZ2ZmZWViYGNjZmRjZWRoZ2VhX2JjY2JiYGFhYGBfY2dnY2FiY2BiX19fX2Fh
|
||||||
|
YWJgY2JjYGFgYV9dXF5fYFxfYWJkYmJeX2BiYmFiYGFkZGJfX19iZGlhYGBkZGJj
|
||||||
|
YmRlZWRhYWBhYmBcXV1dXVxbW1xbW1ZXVFBXVFNUUFRUUk5RVldQT1FPTkxMT1JR
|
||||||
|
UFFRUFBRU1NRUFBRU1RRUlRVUlNWWFhaWV1eW1tdX2BgXllYXV1bXWBgZWNgYV9g
|
||||||
|
X2JfX2JlY2VmZ2RmZWZiYl9fX19hX2BeW15hYF9dW15gYWRiXVlbXF9hYmNjZWBm
|
||||||
|
YmFdY2RkYWFhXV9gZGFhY2JeY2FeXmFgXl9iYl5dYGFcX15dYF5dXVpZXGBfXl1d
|
||||||
|
W19gYF9cXF1cXl1bX2JeXl9aW11cXF5fYGBhY2ReYF9dYWFjYmFfXlxcXVtdXlpe
|
||||||
|
X19lY2NgYWBeYmJdXl1hY2JiYl5fYGBhYmRkZGJjY2JjYmJiYGFiYmBfXV5eXV1g
|
||||||
|
Y2VgX1xbW1teXVpZW15fXVxeXVteW1lZW1pcXFxfW1tZWmBeWl1eXV1eXlxYWlxc
|
||||||
|
WlhZWFlYWFdbWltdWVlZXFlaW1xaWFdYXFtaWFhYVVZZWVhYWVdWVVZZWFxXW1lU
|
||||||
|
WVhVU1dXU1JVVVZYWVlaWllYWVZWVldWV1hWVlhXXllYV1ZYVlZVW1lYWFRUU1RX
|
||||||
|
VlZYWVlYWFhTWFZYW1xaW1lYWVtZVVZXWVpXWltZXFxaWFpXWV9fWltYVVhdWlla
|
||||||
|
WltZV1hYWVxbV1hWWFxbWl1cWlddWVlbW11aV1daXFlZW1xbWlpeW1pdW1lXW11e
|
||||||
|
W1tbXFhaXl1bX19cW1tcXF5cXF1aV15eWlpbWl5cXlxcWltcXFxbWlpcXFxdXV1i
|
||||||
|
X1tcX11gX2BhYWNhYF1eYmJfXmFnZWBeX2JeX2FfX2FjYWNeX2BfYmRkYWBfXl1f
|
||||||
|
YmNgX2BiYGFhYmNmZmZlZmRjZGVlZWZkYF9kZGNfXl9gX2BjZWVlYmJhZGJlZGJl
|
||||||
|
Y2JkZmRjY2ZnZGVkaGZlamJiYGRlZGNhY2hoZGNiaGVpZmtpZmBkZ2plYmRnaWdl
|
||||||
|
ZWdpZGZnaGdkZGlta2pqaGlnZ2RoamlmZ2pta2lqa2tqbG1sbGtqZmtsamhqbGlr
|
||||||
|
aGloa2dnbmpwZ2lra3uly+Hv+P7/////////cHR9e3x6d3Z3eX16eXh3d3p6dnh3
|
||||||
|
e3l0dnVxc3Z3dnd5dHV2eXh1c3N0d3Z4eXl8fXyAenl4c3RzcnJ2enZ2dnV0dnl+
|
||||||
|
e3d0c3V2dXR4eHh2dnZ1eHZ2dHh4d3V3dXR1dnZ1dHR0dHd3eX97eXl2d3R1dnd2
|
||||||
|
dnd5c3JzdXJ1c3Z3dXZ2eXRwc3FycHBwbnBvbnB3dXV1c3RwcW9ydXJzcnR3eHZ1
|
||||||
|
eHR0dXRzb29wc3FwbXBtb21ubWxtcnNxbm1rb3Fubm9ubm5vbmlqbmxpamxvbW1s
|
||||||
|
bm9vb3FycHJsamtra21rbW1vcG5xb25tbGlpbWttbmxsbGxpa2hoamtrbWxqamxt
|
||||||
|
bW9ub21rbnBoamdlZ2ppbW5tbW1vbmxqZWdmY2VlZGNjZWZlYmVjZGBiZGBfYmJp
|
||||||
|
Z2NkZWNgX2NjYmNhX15lZWBdYF5iXVxbYWBgYmJgYF5gX15cX19jY2BeXmBfYGJi
|
||||||
|
YV9gYmFfYWJjYF5gY2RiX2FdYWJlZGRkZWVmZ2NhX2FhXmNiXVtcXV1dXVxaWFZX
|
||||||
|
WFVUUlNTU1VTVVNVT05QUFFNTU5MTU9RT1JTUFBRU1BRU1VUVVVTU1NWVFZaW1pY
|
||||||
|
WlpaX11eX15cXVxdXlteXF5hZF9fX2BiYWFgXmBhYmJiZGVkY2RjYGBfXWBiXVxg
|
||||||
|
YWJhX19jYF9hYGFfXFpbXWJjYmFgYGFiYmNiY2VhXV9fZmNkYWFiZGNjYF5cXVtb
|
||||||
|
Xl5eX2RkZF9eXF5dYF5hXlxbXFlYW2FiY2JfYlxZXl5dXV9dXV5gXl1cW1tbWVpd
|
||||||
|
Yl9fYl9eY2FdXV5eXlxdXFtbXmBgYGJiYmhlX2FeXl5fYF9fX11fYGBiYGFiYWFl
|
||||||
|
Y2NiYmBiYWJnZ2FfY2NgX2JkYmNlYl9fYFxdXV5fXVxZWlpdXF1cYF9gX19eXlla
|
||||||
|
XWBiXlxYWFxcXVtdXFpfXmFgW1lbWlpYW1pbW1tZWFtdYF1aWVpZXWFfWFZUVlZX
|
||||||
|
WVtaWFZWWVZUV1dYWFVUVFZVWFxcXVtaW1hWVlVUU1ZXWVhbWFlWVFhaW1lYVlVU
|
||||||
|
V1pYVllZWFdaW1pYWFtVVlpcWlRUWFdXWVlWWVtbW15YWVtbXFtXWllWVVdZVlZY
|
||||||
|
V1hZWFlYV1daVVZZV1tcXF5cW1paWVheXl5dW1xcWVpbWFhXWllYW1hZXlpWXFxc
|
||||||
|
W15aWVpZWllZW15dWlxbW1lbXVxaXF5cXFpaWlpbXVtcXFxcXl1aWFpcYWNfXFxc
|
||||||
|
XF1dX2FaWVtaWVpbXVxbVltaWVpfXF1cYWBeYWFeX19dX2FfXmBfX2NqZGFfYGJg
|
||||||
|
YGBjY2VhYGFmZGFgYWJgYV9eXl5fYmNiYWJiYF9eX15gYGBiYGFjZGNjY2JjZmdj
|
||||||
|
ZGFhX2JfYGJhY2RjYWRjYmNiZGBkZmZmZWRkZmVmZmVlZGlmZ2lpaGZmZWdkZWRl
|
||||||
|
aWhjY2FjZmNmaGlnZmtqZ2dkZWdkZWVkZGdkZ2hpamhoZ2ltZmZnZWVlY2dpamtr
|
||||||
|
a25wbWppbW9vcHFxb2xxbGxva2xoamlpaWprbGprb21mZ2h3gqDN4u/3/f//////
|
||||||
|
//9ueHx9fnx5eHl8eXp7fnl4eX14e3l5d3l3dHV0dXZ4dHZ1c3N0dXRzdnR3eXd4
|
||||||
|
dHV6e359eXd4dnZ5d3d3dXZzdHZ0eHh3d3h3dXh1cnB0c3R2d3Zyc3R4enp3eXh4
|
||||||
|
dnd2d3p7e3x6dXh2eHd2dHd5dHR0dXd5d3V0dXR1dHRzdnZ3eHhzdHd4eHJxbmxu
|
||||||
|
b29wcnJzdnV0dXBydnNxcHFwcnV2dHd1dHV3dXRycnRzdHFtb3FxcXBubm9wbG9w
|
||||||
|
b29vbnFycXBsbW1xc3Jtbm9ubW9ubWxtb25wdG9tbm1wcWttbW5sbWtwbnFsamps
|
||||||
|
bGtoaWtvcW9tbGxsa25vbWtoaWtsa2psa2tpbWxqbGloZ2loaWtsbG5tbGxraWlq
|
||||||
|
a2lnZWVlY2JiYGJnY2JkZV9hY2JjYmBga2dhYWNkY2ZkYWBfXmBgXlpdYl9bW11h
|
||||||
|
ZGRhX19fXGFcXWFfX19hXmBhYGBiZGZlY11cXWNkY2ZmYmJgXl9eXmFhZGFjY2Nm
|
||||||
|
Z2hmZGJjYl9eYGNhXl9eXFpcXVxbXFhWU1FRUlNSUE1OUFFNTE1NTUxPT0xKT1JY
|
||||||
|
U1JSUE9SVFZTUlJTVVdZWlhZWlhZWVhdXF9hXV9cXVxeYl9dYWBdXV9gYl9fXmBg
|
||||||
|
ZGNfX2NjY2NkYl9jYGFjY2FfYV5gYV9gY2JhYV9lXWBiXmFjX2BfXV9eXF5dX2Bf
|
||||||
|
ZWNkZWhmX19dYF9jYmFfY2NhXF1dYV1dXFxdXl9gYGFdXGBeXmFhXFtdXVxcXl5g
|
||||||
|
YmFeXVtcYGBcXl9dYFxfXl9fXl9eXV1eYWBeXVxdYGNhX2FfYWFgYV9eYGNgYWJj
|
||||||
|
X19gX11cXl5dXl5hX19hYWFkZGJiZGNiYmJjYWFjY2FfXmFkY2RlZmdhX2BhXmBi
|
||||||
|
ZGRiY19dXVxZXF1eXV1gYV9eYl5hX19eX2JdWl1cXVxcXmFeXF5eXV5bXmBkXFla
|
||||||
|
WFtbWltbWllbW1hbWVlZWltZW1hXWFdaWlpZW1tVVldYV1ZXWFRWU1NWV1hYWVpY
|
||||||
|
V1hWVlRTV1ZXVlVTUVNaVlVUWFdVVVNUWl5bWldYWFpbWlhZV1ZYVldcWltaWVdY
|
||||||
|
WVdVV1lbW1hXWFpXVVZWVlVUV1dZVVVVVVZVWFpXVlhaWlpYWFtaXWFdWllZWltb
|
||||||
|
W1pbW1lYWVxZWFhUVlhZXF9bWVtYXFxcW1pdXV5YWFlXWltcWldaWVlbW1pXV1pa
|
||||||
|
W15hXVxgXVlZW11aW1laW11bXF1ZWmBcXFxdXF9cX15aWlpZXFteWl1gYl9hW1la
|
||||||
|
Xl1eXV1eXV9dXl1dXV9hYGFhX11dX2BgX2RlZWNlYl9hYWNgX2BfW1tdXV9iZGJg
|
||||||
|
YF9gYGNiYGFjZ2FgZGFgYWVhY2ZkZWdgYGBmZGFgYWFiYmBfY2RlZWRkZGVkYmVn
|
||||||
|
Z2RnamdoZ2VjY2ZnZGJiZmplZmVlaGNkZ2ZmZWFiY2ZmZ2trbGtpZ2hqa2xqaGZn
|
120
test/search_test_data/0002e.pat
Normal file
120
test/search_test_data/0002e.pat
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
5eXl5uXk5eTl5eXl5eXm5eXl5eXl5ebl5ufl5efl5ebm5+bm5ubm5ebm5ufm5ufm
|
||||||
|
5uXm5+bl5+bl5ufm5+bm5ebn5ufm5ubn5+bm5+bm6Ofn5+fm6Ofn5+jn5ubn6Ofn
|
||||||
|
5+fm5+fn5+fn6Ofo5ujo5+fo5+fn6Ofo6Ojn6Ojn5+nn5+fn5+jn5+fo5+fo6Ojn
|
||||||
|
6Ofn5+np6Ofo5ufo6Ojn6Ojn6Ojn5+no5+bn6Ofn5+fn5ufn5+fo5+fo5+fm6Obn
|
||||||
|
6Ofn5+jo6Ofo6Ojn6Ojo6Ono6eno6ejo5+jo6Ojo6Ono6Ono5Ofo6Ono6ejo6Orp
|
||||||
|
6ejp6enp6Ojo6Onq6Onp6ejo6eno6enp6eno6ejp6Onp6enp6unp6eno6Onp6unp
|
||||||
|
6ejp6enq6ejp6unp6enp6Ono6eno6uno6enp6Orp6enq6uno6unp6enp6erp6Orq
|
||||||
|
6Onq6eno6unp6unp6urp6urq6enp6urq6uno6urp6erp6erq6urp6urq6erq6uvr
|
||||||
|
6erq6enq6ejq6urp6uvr6erq6urp6unq6unq6Orp6+nq6unp6err6unp6+rp6urp
|
||||||
|
6ejq6erp6enp6erp6erp6eno6ujp6unq6+rq6urp6+vq6uvr6urq6urp6+rq6urr
|
||||||
|
6+nq6unq6urq6uvr6+rq6uvr6+rq6uvq6+rr6urr6uvr6+vr6+vq6+vr6+zr6+vr
|
||||||
|
6+zr6+rr6uvr6+rr6urq6+vr6uzr6+zs6+zs6+zr6+zs7Ovr7Ozr7O3r7Ozs7Ozs
|
||||||
|
7e3s7ezr6+3r7Ozs7e3t7O7t7O3t7ezt7u3t7u3t7u3t7+/t7e7u7+7u7+3u7+7v
|
||||||
|
7u7u7u7v7+/w7u/v7/Dv7+/w7+/v7u/w7+/w8O/w8PDw8PDw8PHy8PHw8PHx8PLx
|
||||||
|
8fLx8vGVjoV7dW1kYmJYVlRVVFRWVldZW1xdYGJjZmlqbG5wcnZ3en1+gYKFh4qL
|
||||||
|
jY6OkZKTlJaXmZqdnqGjpqipq6yur7Gxs7S0tLa2uLm5u7u9vr7AwMHCw8PDxsbI
|
||||||
|
ycrJy8zNz8/S09PU1dfX2dnZ2dja2tra2tvb2tra2tvb29rb3Nzd3d3d3t/e3d/f
|
||||||
|
3t/f39/f197f39/f3+Df39/e3t7e3t/f3d7d3t7e397e39/e3uDg4ODg4OHh4ODg
|
||||||
|
4d/f3+De3uDf39/g3d7d3Nza29va2tja2tnZ2NjW1tjX1tbW1tXU1dXV1dXV1dXV
|
||||||
|
1dXW1dTT09PS0tLS0dHS0NHR09PS09LT0tTU1NPT0tPT09TS09PT0tLR09PT09PT
|
||||||
|
09TU1NTU1NTU1dXV1dXU1dXV1dXV1dXW1tXX2NfX19fX2djZ2dnZ2drZ2tvb2trb
|
||||||
|
29vc29vb29vc3Nzd3N7d3d/e3d7e397f3t7e39/f3uDg3t/g4OHg4ODh4d/h4OHh
|
||||||
|
4OHh4eHh4eHi4uLi4uLj4ePi4+Li4uPj4+Pi4uPj4+Pj4+Ti5OPj4+Xj5eTk5OTk
|
||||||
|
5OXj5OTk5OTk5OTk5OTj5OPj4+Tk5OTj5uXl5OXl5OTl5eTl5OXl5ebl5ebk5eXl
|
||||||
|
5ubk5OXn5ubl5eXl5uXl5+Xk5eXl5ebl5ebm5ubl5uXm5ufn5uXn5ubn5ubm5+fm
|
||||||
|
5ubl5ubn5ufm5ufm5ujn5ubn5+fn5ufm5+jo6Ofn5ubm5+bm5+fn5ufn5+fo6Ofo
|
||||||
|
5+bn5+jn5ujn5+fn5+fo6Ofo6Ojn6Ofo6Ofn6Ojp5ufo6Ojo6ejn6efn6eno6ejo
|
||||||
|
6Ojo5+fn6Ojp6Ojo6ejo5+no6Ojo6Ofo5+fo6Onp6Ojn6Obn6Ofm5+fn6Ojn6Ojo
|
||||||
|
5+jo6Ojo5+jo6Ofo6Onp6Ojo6Ojn6Ojo6Ojo6eno6ejo6enp6Ojp6ejp6unp6Onp
|
||||||
|
6enp6Onp6Onp6eno6Ono6enp6enp6Ono6enp6OXp6Ojq6ero6unp6unp6enp6unp
|
||||||
|
6unp6eno6enp6urq6enp6enq6unq6enp6erq6urq6unq6unp6Orp6enp6erq6erp
|
||||||
|
6erp6urq6urq6enq6+rp6urq6unp6ujp6unq6enq6evq6unq6unq6uvq6unq6urq
|
||||||
|
6+vp6ujq6unq6urp6unq6unp6+rq6evq6urp6unq6+rq6urq6erp6urr6+nq6urp
|
||||||
|
6unq6+nq6erp6erq6erq6erp6urq6urq6evq6enp6enp6ero6unq6+nr6urq6+rr
|
||||||
|
6urq6uvr6urq6+vr6+vq6+zq6+vr6+vq6urr6+rr6+vr6urr6urq6+zr6+rq6+vr
|
||||||
|
6+vr6uzt6uvr6+vr6+vr7Ovs6+vs6+zs6+vs6+rr6+rr6+vr6+vr6+vr6+zr6+zt
|
||||||
|
7Ozr7Ovr7Ovr6+zt6+zs7e3t7O3s7O3t7ezt7O3t7ezs7O3u7ezt7O3s7u3t7e3u
|
||||||
|
7ezu7e3u7e/u7u3u7+3u7u/u7u/v7u/u7+/v8O/v7+/v7+/v8PDv7/Dv7+7v7/Dx
|
||||||
|
8PDw8PDx8PHv8fHy8PHw8fDx8fHw8fHy8vLy8qOdlpGLhH56dXRycHFxcnR1d3l6
|
||||||
|
fH+ChIeJi42PkpSWmZyfoaKmqKqrra+vsLK0s7W3uLm6vL2+wMLExcfGyMrKzczN
|
||||||
|
zs/OztDQ0tLT09TV1tbW1dfY2NfY2dra2trc3Nzd3N7e3t7e39/f39/f4ODg4ODg
|
||||||
|
4eHg3+Hh4eDg4OHg4ODh4uHh4OHh4uHh4eHj4eHi4OHh4uHi4eDh4eHg4eHh4eHi
|
||||||
|
4eHg4eHg4eDi4eLg4eLj4+Li4+Li4+Hi4eLg4eHh4uHi4uLh4OHg4eDh4N/e4ODf
|
||||||
|
4ODf397e3d/f3d7f393e3t/d3t7d3d7d3d3d3d3d3tze3d3c3tzb3d3d3Nzc3N3d
|
||||||
|
3d3e3d3d3d3d3d3d3t7e3tze3d3e3d3e3dzf3d7e3d7d3t7d3t7e3t7e3t7e3t7f
|
||||||
|
3eDg3+Df4N/f4ODf4N/g4N/g4ODh4OHh4eHg4eDi4eHi4OHh4uHh4uLh4eLi4uLj
|
||||||
|
4eLj4uLj4+Lh4uPj5OLj5OLj5OPk4+Tk4uPj4+Tj4+Ti5OPk4+Pj5OTl5OXj5OTj
|
||||||
|
5OPk4+Tk5OXk5eXl5eXl5ubm5eXl5eXm5uXk5eTl5ubl5eXk5Obl5eTj5OXl5OTl
|
||||||
|
5uXm5ubl4+bl5uXl5ebk5uXl5eXm5uTm5ubn5ubm5uXn5ubm5ufl5ebm5uXm5+Xm
|
||||||
|
5ufm5+fm5ebm5ubn5ujn5ubl5ubn5ufn5ufn5+fn6Ojn5+fn5+jn5+fm5ufm5+fo
|
||||||
|
5+fn5+nn5ufn5+bm6Ofm6Ojn5+jo6ejn6Ofp6Ojo5+jo6ejo6Ojn5+jp6ejo6Ojo
|
||||||
|
6eno6Ojo6Onp6efn6ejo6Ojo6ejo6enp6Ojo6ejo6eno6ejp6eno6ejo6Ojn6Ono
|
||||||
|
6Ojp6enp6Ojp5+fo6Ojn6Ojo6ejo6ejo6enp6Ofo6ejo6ejp6Ojo6eno6ejp6erp
|
||||||
|
6Ono6Ojo6eno6eno6enq6erp6uno6ero6Orp6unp6erp6unq6unq6urp6uno6ero
|
||||||
|
6Orp5eno6erq6urp6unp6erp6Onr6erp6+nq6unq6enq6+nq6urp6urq6erp6urp
|
||||||
|
6urq6urq6urq6urq6+rp6+rq6uvq6Orq6unr6urs6urr6urp6unq6urq6urq6+rq
|
||||||
|
6erp6urp6urq6urq6urq6err6err6+rq6+rr6urq6+rr6urr6urq6+vq6uvq6+zq
|
||||||
|
6urr6uvr6+vq6+rr6urr6uvq6uvq6uvq6+vr6urq6err6evq6uvr6urr6urp6urq
|
||||||
|
6+rq6unp6urq6urq6urq6uvq6urq6+vr6+vr6+vr6uvs7Ovr6+rq6+vq6+vq6+vq
|
||||||
|
6+vq6+vr6urr6+zq6uzr6+zr6uvs6uvs6+zr6+zr6+zs6+vr6uzs7Ozs6+vq6+zr
|
||||||
|
6+zs6+zr6+zs6+zs7Ovr7Ovs7Ovs7Ozs7Ozs7Ozs7O3s7Ozs7Ozt7O3s7Ozs7u3t
|
||||||
|
7e3t7O3t7e3t7e3t7u3u7e3u7e3t7e3t7e7t7u7u7u7u7u3v7u3v7+/u7+7u7+7w
|
||||||
|
7+7u7u/w8O7v7+/w8O/x8PDv8PDw8fHw7/Dv8fHx8fDx8fHx8fHx8fHw8fHx8vLy
|
||||||
|
8vLxs6+qpqGcmJWRkI6Oj5CQkZOVl5mbnaCipKepq62wsrS2uLu9vsDDxMXGx8jI
|
||||||
|
yszNzc7P0NDS0tLU1dXY2NjY2dnc3Nvc3Nzc3Nzd3d3d3t7e397e4N/f39/g4eHh
|
||||||
|
4OLg4eHh4eHi4eLh4uDh4uHi4eLi4uPi4+Hh4ePh4uHi4+Lh4uLj4uLi4uPi4uLj
|
||||||
|
4uPi4uLi4uLi4+Pi4uPi4uHi4uPj4uLj4uLi4uPh4eLi4uLi4+Li4+Pj4+Li4+Pj
|
||||||
|
4uLi4uLi4uPi4+Lh4uHi4uLi4uPi4eHi4eDh4eHf4eHh4eLi4OLh4ODg4eDh4eHh
|
||||||
|
4eDh4eDh4eLf4eHg4N/h4ODi4ODg4OHh4eDg4OHh4eDh4uDg4uHi4eLg4OHh4eDh
|
||||||
|
4OHg4uHh4eHh4eDg4eHi4eHi4eHi4eLh4uLi4uHi4uLi4uPj4uPj4uHi5OPk4+Pj
|
||||||
|
4+Pj4uPk5OLi5OPj4+Pk5OTi4+Pj5OPk5OPj5OPk5OPk5OTk5OXk5OTk4+Tl5eTk
|
||||||
|
5eXk4+Tk5OTk5OXk5OXl5eXk5eXm5eXk5OXk5uXl5ebl5uXl5ubn5eXm5ubl5ubm
|
||||||
|
5uXl5eXm5uXm5uXl5eXl5eXk5eXm5uXl5ubn5ubl5ubl5+Xm5ubm5ubn5ubn5efm
|
||||||
|
5+fm5ubn5+fn6Ofn5+fm5ufo5ubn5+bm5+fn5+fn5+fn5+jm6Ofn5ujn5+fn5+fn
|
||||||
|
6Ojo6Ojn6Ojn5+jo6Ofn6Ofo5+fn5+jo6Ofo5+jn5+jn5+jn5+jn6Ojo5+jo6Ono
|
||||||
|
5+no6Ofo6Ojo6Ofp6ejn6Ojo6Onn6Onp6enp6eno6efo5+jo6Ono6Ojo6enp6Ojo
|
||||||
|
6enp6enp6Ojq6Ojo6eno6Onp6ejp6unp6ujq6unq6enp6Ojp6Orp6Onp6enq6enq
|
||||||
|
6eno6Onp6eno6ejp6eno6Onp6erp6ejq6eno6erp6enp6enq6urp6Onq6unp6urp
|
||||||
|
6+nq6enp6enq6unp6erp6+nq6enp6unp6enp6erq6unr6uvq6erp6+rp6erp6unq
|
||||||
|
6urq6urp6urq6err6uvq6urq6urp6+rq6uvr6uvq6+rp6urq6urq6uvp6+nq6urr
|
||||||
|
6unq6+vq6+rr6urq6urq6uvq6urp6urq6urr6urq6urq6urr6+rr6urq6uvq6urr
|
||||||
|
6uvq6erq6uvr6+rr6urr7Ovq6uvr6+vr6+vq6+vr6+rq6+rr6+vr6urq6+vr6uvq
|
||||||
|
6uvq6+vq6+zq6uvr6+rq6uvq6+rq6urr6+vq6urq6+rq6urq6uvr6+vq6+rq6uvr
|
||||||
|
6+zr6+vr6uvr6+vr6+vs6+vr6+vr7Ozr7Orr7evr6+rr6uvs6+vr6+rq6+zs6+vs
|
||||||
|
7Ovs7Ozs7Ovs6+zs7Ozs7Ovs6+zs7Ovs7Ovs6+zs7O3s7Ovs7Ozr7Ozr7Ozs7Ozs
|
||||||
|
7O3s7O3s7e3t7Ozr7Ozs7uzt7ezs7O3t7uzs7e3t7uzt7ezu7e7t7u3u7u7u7e7u
|
||||||
|
7e7u7u/u7u/v7e/u7+7v7+/v7u/u7u/w7+/v7u/w7vHv7u/v7vDw8PDw8PHx8fHx
|
||||||
|
8PDw8fDx8PLx8vLx8fDw8fHy8vLy8vLy8/MAEAEAAAMAAAABBJcAAAEBAAMAAAAB
|
||||||
|
Bt4AAAECAAMAAAABAAgAAAEDAAMAAAABAAEAAAEGAAMAAAABAAEAAAERAAQAAAAQ
|
||||||
|
AB+FwAESAAMAAAABAAEAAAEVAAMAAAABAAEAAAEWAAMAAAABAG8AAAEXAAQAAAAQ
|
||||||
|
AB+GAAEaAAUAAAABAB+GQAEbAAUAAAABAB+GSAEcAAMAAAABAAEAAAEoAAMAAAAB
|
||||||
|
AAIAAAFTAAMAAAABAAEAAIdzAAcAAASkAB+GUAAAAAAAAAAIAAH9gQAD+voABfhz
|
||||||
|
AAf17AAJ82UAC/DeAA3uVwAP69AAEelJABPmwgAV5DsAF+G0ABnfLQAb3KYAHdof
|
||||||
|
AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15AAH9eQAB/XkAAf15
|
||||||
|
AAH9eQAB/XkAAf15AAGq2yWAAAAAIAAAJYAAAAAgAAAAAASkYXBwbAIgAABzY25y
|
||||||
|
R1JBWVhZWiAH0wAHAAEAAAAAAABhY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAA9tYAAQAAAADTLWFwcGyYcjd2/nI/x5EwPxA3BfUzAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAVkZXNjAAAA5AAAAEF3dHB0AAAAwAAAABRrVFJD
|
||||||
|
AAAA1AAAAA5jcHJ0AAAEYAAAAEFkc2NtAAABKAAAAzZYWVogAAAAAAAA81EAAQAA
|
||||||
|
AAEWzGN1cnYAAAAAAAAAAQHNAABkZXNjAAAAAAAAABVTY2FubmVyIEdyYXkgUHJv
|
||||||
|
ZmlsZQAAAAAAAAAAAAAAFVNjYW5uZXIgR3JheSBQcm9maWxlAAAAAG1sdWMAAAAA
|
||||||
|
AAAADwAAAAxlblVTAAAAKAAAAw5lc0VTAAAAMAAAAYpkYURLAAAAPAAAAjZkZURF
|
||||||
|
AAAAOgAAAeJmaUZJAAAAMgAAAMRmckZVAAAALgAAATBpdElUAAAALAAAAuJubE5M
|
||||||
|
AAAAKAAAAnJub05PAAAAKAAAAbpwdEJSAAAALgAAArRzdlNFAAAAOgAAAPZqYUpQ
|
||||||
|
AAAAGgAAAV5rb0tSAAAAGgAAApp6aFRXAAAAEgAAAXh6aENOAAAAGgAAAhwAUwBr
|
||||||
|
AGEAbgBuAGUAcgBpAG4AIABIAGEAcgBtAGEAYQAtAHAAcgBvAGYAaQBpAGwAaQBH
|
||||||
|
AHIA5QBzAGsAYQBsAGUAcAByAG8AZgBpAGwAIABmAPYAcgAgAEIAaQBsAGQAbADk
|
||||||
|
AHMAYQByAGUAUAByAG8AZgBpAGwAIABHAHIAaQBzACAAZAB1ACAAUwBjAGEAbgBu
|
||||||
|
AGUAdQByMLkwrTDjMMowsDDsMKQw1zDtMNUwoTCkMOtjg2PPVmhwcJaOgnJfaWPP
|
||||||
|
j/AAUABlAHIAZgBpAGwAIABHAHIAaQBzACAAcABhAHIAYQAgAEUAcwBjAOEAbgBl
|
||||||
|
AHIARwByAOUAdABvAG4AZQBzAGsAYQBuAG4AZQByAHAAcgBvAGYAaQBsAEcAcgBh
|
||||||
|
AHUAcwB0AHUAZgBlAG4ALQBQAHIAbwBmAGkAbAAgAGYA/AByACAAUwBjAGEAbgBu
|
||||||
|
AGUAcmJrY89O6gAgAEcAcgBhAHkAIGPPj/Blh072AEcAcgDlAHQAbwBuAGUAYgBl
|
||||||
|
AHMAawByAGkAdgBlAGwAcwBlACAAdABpAGwAIABTAGMAYQBuAG4AZQByAEcAcgBp
|
||||||
|
AGoAcwBwAHIAbwBmAGkAZQBsACAAUwBjAGEAbgBuAGUAcsKkzpCxCAAgAEcAcgBh
|
||||||
|
AHkAINUEuFzTDMd8AFAAZQByAGYAaQBsACAAQwBpAG4AegBhACAAZABlACAAUwBj
|
||||||
|
AGEAbgBuAGUAcgBQAHIAbwBmAGkAbABvACAARwByAGkAZwBpAG8AIABTAGMAYQBu
|
||||||
|
AG4AZQByAFMAYwBhAG4AbgBlAHIAIABHAHIAYQB5ACAAUAByAG8AZgBpAGwAZQAA
|
||||||
|
dGV4dAAAAABDb3B5cmlnaHQgMjAwMyBBcHBsZSBDb21wdXRlciBJbmMuLCBhbGwg
|
||||||
|
cmlnaHRzIHJlc2VydmVkLgAAAAA=
|
136
test/search_test_data/0002f.pat
Normal file
136
test/search_test_data/0002f.pat
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
TUxOT1JVUFNUVlVRT1VYWVdXUlJUT1FPU1VPT01PUE9WVlFSUFJRTkxKTU1PTEtJ
|
||||||
|
R0JDR0RDQEBBQD8/PDs/PD0+Pz44NzY1NjY5ODw5OT08Nzk5ODs8QUNBQj9BQUND
|
||||||
|
QklLSk5KSU9TXlhLT0xWUlFaVFdMTVdVW1VgWVdWXV9dWFtWUlFSTkVERTk1NTUz
|
||||||
|
MzUzNjU0ODg1ODY2Nzk6PTo6P0NETE1JR1RSTFBISkpKVVVLSUpUTU5STVZRVFpT
|
||||||
|
Vk5XXGBYUFhVWFJTV19kXVdVUFdVVlZUW1xbWlhZV1pcWE9TWlRWWVlXUE1MTlJD
|
||||||
|
PDo8Ozo+P0pOTVhWVFJWW15oYFxbXlpUVlpZXFhYVVdXUFlcYFhUVFdaW1RQXVxc
|
||||||
|
XltXUVBSTU1RUVRYVVNNSU1RUFFWVFFST05QUk9OSU5QTk1KS1BVSkxLTE5LT1RO
|
||||||
|
VlRZWlZYVE1FRkVHR0ZLSU9LTlFOXWaJo7CspZ2WlZOJfXFmYmFqdG9eS0E+OTk4
|
||||||
|
ODtBQTw9Ojg5PD5EQT8/P0BAPDc6OEE+Pzo+QENAPDtBQENDRkNDR0A6QEQ8ODU0
|
||||||
|
MTQ3NTg3Mzc2NDg0OTs/RUpTS05JT1xYWVlUXFZWVVtdWVlXUE5TUlJQT1BUVlZR
|
||||||
|
VFVYW1NRTkxMUlZUUEtMTk9PTE1MSERESUpLSkxJRklJSUtLRkRJSEVCRENERUZE
|
||||||
|
QkNBQ0JEQ0FAPjk6PDo3OTc3ODU2ODY2NTc+Rk9YYmdqaGhna3B3e3x+gYGBgYaH
|
||||||
|
iYuKi4uKioWCfXdwbmpnaWlsb3eCiIuMjYmJjo6SkJCTl5ORjIaBfnZnVEc/Ojo6
|
||||||
|
ODo7P0RJSkxPUlVWWVhWVlVSVFFRT05JRkVARD5BPkBCRERDQ0ZGRUdFSUpKSkpK
|
||||||
|
SklOS0xNTkxOT05MS0tMTk9NT1ZWU1dZWl1eXWJkZ2hqbm91dXV4fH5/gYB/gYOC
|
||||||
|
hYmGiIiHh4iGh4qLi4qMjY2Li4uLjZKTlpeWlpSPjo+SkZOQkpGRlZiXlpaZmZuZ
|
||||||
|
mZibl5mZmJiampual5aYnKCpr7KqmImGiJWosbzAvLu5u7i1tbGwsbKzt7a8vcC/
|
||||||
|
vL29vr6/v7q8vLq8vrq4ube1tLe3t7S0ta2ysrK1tKyginBfXVhTUlBOTVBMTU9M
|
||||||
|
S0tLSUpLSkhJSkdPT05KSUdNS0lJSE1LSkxKTk9MTUtNSk9OTUxPUU5NUE9OT0xM
|
||||||
|
Tk5QUVFQUU9QUVJSVFVSUlNTU1JRTlJTUFBSVFRSUlFTT09RUlBSUVNTUU9QUVNV
|
||||||
|
VVVVUVFSU1FVU1JSUFFSU1hUUVFPUVRQUVJRU1NUVVZYWFZWWlhYVFFVWFhXVlhW
|
||||||
|
WFhaWltbWF5bV1dYVlhbWFZYWVlaWVlYV1laWVpZV1taWVlaWlpaWVtcXV1cXF1d
|
||||||
|
YF9dYF5dXV1dYF5bXV1cWlxWV1dYV1ZWWFdYV1ZZXIO9ydPa3uHk5efo6el7enh5
|
||||||
|
ent8eHd1dnl2dnh6enl4eXdwZ1pMR0VFSkVEQz09Q0hKQ0A/P0I/PEJCQT4+PTpA
|
||||||
|
RURFQ0RHQ0RBPT5ARkhJSkxMTk1JS05QTklKTk5QUVNUU1FXU1ddWVVRUFFTU1JQ
|
||||||
|
UlBQT0tRVVVVU1JSUFJNSktPT0tJSUhHREVFQ0dEQkNAPj0+PTw7Ozs6OTw2Nzk4
|
||||||
|
ODg6PDs5OTg3Nzs4Ojw7Ozw9PURBQkQ/RktGS0tISUpRVU5RTUpTT1lTV1VOVlNc
|
||||||
|
WV1cWVddY1xdXllPT1JVT0pAODc1MzU5Njc6OTs3Njg2NTc7ODg4OTg+Q0dPUEpH
|
||||||
|
VVRMUUxRSkpUTklOSVNSTU1KV1RSWlFYVFRVWVdNUFJeVFRVYWFdXVZQUVVYV1VZ
|
||||||
|
VFdYWVhZXGVhVlRbW1pXUU1LTFBMTkhAOTg6OTk7Q1BSVVldWFpeXmFhY2VjXlNR
|
||||||
|
U1BXWFVVUVZYWFdWU1NTVVZaV09WWVlaWlNQTUtOUE1OUlhZVFFXUE1NUFBQTlFS
|
||||||
|
UFJWTU1OS0pRSkVJUFBNSkpNUEtPVFVXV1lXVldXU0hGRUdJSVBJSUhOVE9RWnWU
|
||||||
|
qauroZiVkYl8c2xmY2VrdWlSQTs6Ozg7OTw8Oz08PDw7Ozw7PTtAPj09Pj1BQUJA
|
||||||
|
OTo+QUQ9OD1FQUM+RUJCOzY9Q0E4ODU0NDY2NjQ0MzI1Njg4Oz1ESkpISkpTWlhY
|
||||||
|
W1ZZV1hTVldOUVNOTE5OUlFQVFlYU01XV1dWU09MSktOUlRTUU1PT0xQTklFR0ZL
|
||||||
|
TU1LS0dHR0dJSkpGRUNGSExHQ0RDREVBQD9APz5AOzs+QD88Pjw4NjY0Njc5Nzg7
|
||||||
|
QUpTXmRmaGdoaGxwdHp7fXmBh4eHhoyQj5CNjYuJhYJ8dnN1b2xtbGtze4SJjI6M
|
||||||
|
iImOj5KUlpWVk5GQi4B3a11RRj5APkFAQUFCSEpLTVBQU1hYWFZWV1NRUlBQTkxJ
|
||||||
|
RkdDQT5AP0NDQkNARERJR0lJRkhHSUtQUE1MS0tNTExNTE1NT1FSUFBVVVVXWF1f
|
||||||
|
XmNjZGdsbG5zdXZ1dnt9f4CDg4F/goOFhYaGh4uHhoWJi4mKi4mIiouNjIuMkZGR
|
||||||
|
lpSUj5GQkpKSkpWTkpaXl5OVlpmbmpiYmZmZmJqWlZeYl5iZmp+jqrO5s6aTgXeB
|
||||||
|
mK64vby7urq9ure0srSztba1t7m9vsDDwr69vb+9uru+wL69vbi3tbSztbq1tLe4
|
||||||
|
rrOztrW1saylknplXFZUVVNPTU9PTk5NTU1NSkhISkpJR0lKS0lKUEpKS0xPTVBL
|
||||||
|
TUxKS01KTExMTkpPTktQUE5PT09QTU5NUFBSUlNST1BPT05ST05PUVFTVlJSU1NS
|
||||||
|
UlRTUVJTUVBRUU5RTlFSU1NQTk5NUFVTUlBSUVBRVFRTU1NSVFJQUlVUVlNUVFFS
|
||||||
|
UFNVU1JUVVVWVVZXV1VWV1dWVVVYWVhZW1pYWVtdXF5aW1hZWFZZWVhYWlpYV1dY
|
||||||
|
WFZXW1tZWFlYWVhWWVlZXFxcW11cXltcXltdXlxdX19dXl5bXVtbWFlYV1VXV1ZU
|
||||||
|
VlVVVVdgfLvJ0dre4eTm5+jp6nl7e3x7eHp6dnh5dnd4dXd4dnZ5cmlgUkhCQEJH
|
||||||
|
QEM/PkFCRERBQERDQz4/QkU7PD1CPkBBQUFAQEFDR0I9PENCR0dISEdJTklMT01P
|
||||||
|
UlFNUFBRUlJZVVVWV1ZUU1hSVFZVUlJTUlBRUVNTVFVSUFFOUE5NTExPTUtIREhH
|
||||||
|
RENDQkJFQj5APkE/Pz87Oj08Oz04Nzc4NzxBODQ1Nzc4Ozo6Ojg2OTs7Ozs+QT9D
|
||||||
|
SUdISEZGRkpQS01LRElHTEpLVVRaWVhZXFtZVlhgX1xXV1BVblVUSkA5NzQ1NDc1
|
||||||
|
NTQzNDQ0NDg1Njc2NTg7PD8+PkpJTUZNT0dPS1JNSFBLRkxIS0hLSk1UVFlgVl5X
|
||||||
|
UVJUVUxRT1ZVUlFZXVpWVFJTVllZV1dUVFtaWltfZl1VWFtcVlZVT0tTUElIR0Q5
|
||||||
|
NzY3Njk/SVJWWmxlWlxdWWBpYV9kV1JUUVJcWlhTT1NSV1pTVFNTVlVXVlZVWFJU
|
||||||
|
WlNPS01VVVpaWVVYV1VWUU5QTk5PUFVRTE1LS0xIRU5KSEpOTk1JR01MSVBVWlxT
|
||||||
|
VFhcWFpZTkdDQEFFS0VISElTUU9WYniWpqiooJeOhn92a2NgYGZwbV5JOzs/QkI7
|
||||||
|
ODs9OkA+PDw6OT1APj4+SDw6Oz4/QkA7O0A9Pz5CPDs8QTxDQkJJPzpBPzo8Ozg2
|
||||||
|
NzQ3NjczMjQ2Nzg7PT9HS0RJR01SUldSUE9OT01VWFJWVE5LTlFTUlBSVldSVFhW
|
||||||
|
VFJWUVBNTEhLTFJUTExNS05OSUZITE1LS0pKT0pGREVGRkdIRklKSUlERURCQ0NC
|
||||||
|
Q0E+PDk9QD9BPzw6ODo4OTo9Ojg5PUdQW2VqamlrbWttcnd6fH19fYKDiI2Ojo2N
|
||||||
|
jo6LjIiIhX58eXVzcW9sb3d/hIyOkI+Lio6QkZOYlpSTjYuHgXJkWE1IRD89QEJF
|
||||||
|
RUZMT0xPUVNUVlhaW1lXVVNSUlJPTUtNS0dDQUJEQkJDRUZGR0hFR0dHQ0dHSEtI
|
||||||
|
SEtJS05LS0xSUVNQTlFUUlVZWFlcXWFlZ2hsbW9zcnV8fH9+fX+AgYGBg4SEg4KD
|
||||||
|
hYOCh4eHh4eJi4qKi4uOjI2KjpGSlZWUmZaSkpeWkI6TmJWYmpiXmJiampuXnJmY
|
||||||
|
lpaZmJqYmZmbnJ2jrLGwsbSwopSDfIeXrLu/vr28urq4s7OzsrK0trW3ubu8v8G/
|
||||||
|
v7++vr27ur27vLy7ubW2uby7t7e1ube1tbe2tLW0sa+mmIFmWldXUlBRT0xOS0xO
|
||||||
|
TVJPTUtKR0lKTEpKTUpJSUlLTUxJTE1PUExJS0tNS0xOTU5MS0xLS09PUVFTUE9R
|
||||||
|
UFNSU1FRVFJNT09OTlBQUlNSUVBRT1JUVFFPUVRUUVNRUE5QUVFSUFFPSk5RUE9P
|
||||||
|
UVNTVlFRTFBPUVJSUlJRT09SUlBQUE9RUlJTVVVTVFVWV1ZYWFZYV1hVVVRTV1ta
|
||||||
|
W11bWVxaXV1aWlpcWllZWllaXV5bV1dXWFpZWldXWVpZVlVXWVlbXFxaXF9cX11f
|
||||||
|
XFxcX15iYWBdXFhaW1pfXFtZV1RWVllXU1NXW2Z9usjT2d/h4+bn6OnpeXp7enl7
|
||||||
|
d3t7enl6eHp4eHl1dG9rZFtRSkdDQkBAQUY/PEVESUREREM9QUFEQUVBPT9BPT8/
|
||||||
|
Pz8+QT5BRENHQkNFRkhJS0xNTkxQTE1SU1NQUlNRUlVWVVVZWlZVU1VWU1ZWVFJQ
|
||||||
|
VlJPUFNXWFZVU1RUUFFPTkxISEdJTEpGREJCQUBAQENHQj07PTo8OzU5Nzc4ODg3
|
||||||
|
Nzg1ODk4ODc5Ozg6ODk3OTk4PD5FQj5AQEBFREU/QlFPSklIR0dHSkxUU1xZUVVZ
|
||||||
|
YFhPU2BaV1RYUU9UWFZKQDo3NzI0NTAyNjQ0Ozg4Njc2Nzk5ODw6Ozo+S0ZLRUdF
|
||||||
|
Q1RMWlVMUU9KT0pPTFVWSlVTVFtTWlNUVlJSTFNOUlRQSlRUWVdaWVVSUldZWlVT
|
||||||
|
U1dUU1pdXFZXW15VVVVOTldSTUdHRzo2NzU2OTk+TV1eYmJYX11aYGleX2lYTVJR
|
||||||
|
Vl5gXFhRUVNYXFJSWl1ZVlFWWlJSU1JcVVhTTlhYWFNTU1lYVVhSTU9RUVRTT05F
|
||||||
|
SEhJRk9NS01OTU9KS1FJTFFRUlNUV1FTV1xdX1lRSERBQkJHRkpJRVJRU1dVYnqW
|
||||||
|
pKekno+Jg3pybWhkZW1yZ1BEPDw+PTs3PDpEQ0E9Ozs7PDs/PEdCOjk9Oz1AQkA9
|
||||||
|
QEFEQj06Ojw7PT9ASUhAPEFCPDg4OTczNDM2NDQ1MzU2ODk6PD5FRk1JUE5WXlJU
|
||||||
|
UkxMTFVVT1BSUFRVVk5ISlNVVVRWWFRUVltYWE9LTUtKSkxJSUhLTU9NSUlMTkxI
|
||||||
|
TU9NR0NHSElLS0xISkhKRkNBQ0RCREJCQz49PDtAPjw6ODg5PDs5Ozg2OkBLWGNo
|
||||||
|
am1tbWtubXB1enp7e36Bg4aGiZKRjo2NjY2LiIiFhoKCd3Vua25vdH2DjI6NjIyO
|
||||||
|
kpGQkpOVko+NiYN4aV5XU01LSUI+PUNHTFFSU05RUlVUWVtcXFZUUlFUU1FPTkxK
|
||||||
|
R0ZCQUBAQUFEQz5CR0pIR0hESUhHRElKSklLS05MUFJVU1JRU1VaWFxdX19iY2lr
|
||||||
|
bW9ycnR3enp5e318fX9/gH6Cg4SFgIOFhoeGh4mMiouOjo6PjY+MjY2RlJKSlJuX
|
||||||
|
lZSUlZaQkpKWl5qTk5aYmpqbm5yampyam5mWl5uenZ+lqK2ytby9tqmcmJiRjJit
|
||||||
|
uL6/vru6uLKuq62vs7a2t7e6u73BwcHAwcG/vcC9vLm4u7e4t7i4ur29urq4tre6
|
||||||
|
uLa5trWzs62onohtXFVUVFJRT01NS0tKS05RS0tKS0xPTklJS0pJSUdLTEtJTEpO
|
||||||
|
S0tHSUpNT05QTk5LS0xQTlBPUFJRTVBRTk9OT05PUlJPUlBQTk9QUFFRT1FRVVNU
|
||||||
|
VFRTUlFWU1JQU1JRUFNVV1RPT1BRT1FSUVNUU1JOTlBPUFBQU1RSUVBSUVNSUVNR
|
||||||
|
UVNVVFRTVVRWVFJTVlhXWVdXU1NTWFtbWl5dXFlZWFhZWFxYVlpYWFlbWVpZWVZX
|
||||||
|
V1dYWVhYWFdXVVRZW1pZWlxdW1peXl1cXGBgX19gYV9fW1pZW1lcW1hWVFVXVVlW
|
||||||
|
U1NVaoS8ytPa3uLk5+jo6el4eXh1eXh9eHt7e3t4eHZ1eHh0cm5jWEtLTEY/PTs8
|
||||||
|
P0NGSklGREVBOz0+RD9BRENAPkE/Oj0+P0A9Pz0+Q0NCQkRJSUlKSUtMTEpLTFBU
|
||||||
|
VlVUVlZSWVteXFpYU1RXWFlVWFlXV1VTVVJPUlZaVldTUVJRUVFOUE1KTE1LSElF
|
||||||
|
QUVEQkVCRUNERD8/Pjs8QDw6Ojo6Ozw5Nzk5PDc2NDQ4Ojg6OTk4Ojc4PEQ7Oj0/
|
||||||
|
PUNCRkNBSUtHSERJTEdKR1BLUVlVV1ZiV1BLU1JVVVZWU1RbWVBJQzo9NzY3NzYy
|
||||||
|
Mjc3ODg0MzU3OTk/Pjo8Oz1ERk9FRkVJSklXUkxWUVBRSlFPV1ZHTU9SXlVdVVdc
|
||||||
|
VlZMUk1QWVJRUFNZWF5eWU9PU1VWVFRSWFBPVllbWlZYWVdUVFFYXFhTUkxKQTo0
|
||||||
|
MjQ1OT5DVFhPV1paYFtgX15gX1FPUlRUWltbVlNPUVdWUlhXXVZVVldaVlNWVllZ
|
||||||
|
VFNPTVNRTVFPUlNUUVVUUlhVU1ZRS0lLRk1LSFFPTVFNTUpLT01LUlRMTVNVU1BU
|
||||||
|
V1tiWFVQSUNDQEVDSEhHVVJYWlBYXn6Ypqiil4qBfHp4cGttcHNtYFBDOz47Ojo3
|
||||||
|
OT07ODo7Oz88OjxAREA8Pj07OjxBQTw4PUFEQTxAPTtBRUVGR0U+QEI+ODUzMzc2
|
||||||
|
Njc4ODQxNDY3OTs8P0RKR0hSTlVfVVtRT09RU1VSUVJTU1JQS05OTVJXVVZUUVNY
|
||||||
|
VVRSTUxOSUtMSktKTEpJTEpKRkdLTE1NT01NSklJSktOTkpGREdGQUFERUREREI9
|
||||||
|
Pj4/Ozc5ODo5Njc6OTs5NzpBSlhja21vb3RxcHBucnp9eXl6fH+EhIWGjo2Njo+N
|
||||||
|
j4+MiYuLhH54cm5tb3BzfYaLjo6MjpKSkpORlJeWkpCHfnNrYVdWVVRMQj0/RE9V
|
||||||
|
UVJQUVFRVFtcXF1dXFlWVlZXV1FRTk9NS0VDQ0FBQUFAP0FER0dHR0dHSUhKSkxL
|
||||||
|
TEpJTlJOUFFUVlNWVltcYGBfZGhnaW5wcnR2dXh6eXt8f4GBgoKAg4GBgoODgoSE
|
||||||
|
iIiHio6Ni4+Sk46KjY6Qk5WVkpGUlJOSlpKSlJWTkpOYmJiYmZial5iZm5mZmpye
|
||||||
|
nZ+foKGip7Cyt7e5vLyznpKcn5aVorO5wcC/wLm2sa2rrK+zuLa4uL2/v768vMDA
|
||||||
|
wsG+wL68vra1tLK1tri8vbi6ubi2tre3tra1tbW4trGroY1tW1hUVFNNTk5KSktP
|
||||||
|
T0tLSkpMSktNTExLS0tLSkxKSUlMTUtLSk5JSE1OTk9MTE9RT0xNUFBRU1BPTU1P
|
||||||
|
UFBTUlFPUlFOUVNRUFFRUU9OUFFTU1NTUlNUVFJTUU5QUlJUVVRUU1ZST1BPUFFS
|
||||||
|
UVBOUVJPUFJSUFJRU1NRUFFSVFNSVFNUVFFRU1RXVlVXVFlYWFhZWFhVWFZUWFdX
|
||||||
|
XV1cWFdYWVdaWFdaVVVaWVlaWVdaWVlYVVdaWVlXWFlbWFdYWVpdW1xcXlpbX2Fj
|
||||||
|
YmBhYV9fX15cXl9aWFlVUFZWV1lYWVlXU1VvorzJ0tre4eTm5+jq6nl3d3l4d3h6
|
||||||
|
ent8fHh2dXN1d3NxbGFUSkdGSEM7Pj89QUhJRkZFQ0RFQ0JCQj09PTg8PUE7Oj4+
|
||||||
|
Qz0/QEFDQkVHR0pJSUxLTU1MTExLT1FSVFNTVVRVWFdXV1ZRUlNWVlVXWFlXWlta
|
||||||
|
VFZXWlxZV1VTVVBTUU1NTEtNS05MR0pMSEVER0ZISEVERD4+Ozs6Ozs6OTk6Ojc1
|
||||||
|
NTY5ODY2Njg2NzY4ODk3PDo4Pjw8PD9CRUFBPT5GRkVLTEZLTVFKSkxSW1daV11Z
|
||||||
|
SlJWVlNSV1pUU1dXVlZQQjo7OTU1NDMyNjc0NTZINzc3OTo8PT07QUJDUkpOS0hN
|
||||||
|
R1RRTlRQTlFIUFJVVEhSUVJgV1ZSWmFeYFJVTk5VUlJQV1lUVVZQSk5OUVZYVFBP
|
||||||
|
UFNUWV1XUlRZWFlXVFVcXlpWWFBCOTIyMzc2PUNNV01TWlpbW1paXl1VVFZXVVZZ
|
||||||
|
V1lcUk1OU1BVXVlaVlNTUVNYVVVbUk9VT05JTE9SUU9QUVZVUlNVWFlUS05LTFFU
|
||||||
|
V09SUFNSUVRNSkpNUk5OV1FNVFpSTlRcYVxYW1FKQ0JER0NFR0hTTFFUTlVWbYma
|
||||||
|
paOelImBfXx7dnRxcXBpWkY9Oj1COTQ5Ozs7QTk6Pzw7Ozs/QEJDPDo6PkBFPjtA
|
||||||
|
QkRFQjk6PUJGREZEQkFCRj04MzQ1ODk1NTM5NzQ0NTk6Oj49P0JFSFRRWFlSXFNS
|
||||||
|
VlZXVVRTU1ZTUFNNTU5PUFRUV1lRTk5SU09MTU5PUVBKS01MSkhIS0pJR0hDR0tL
|
||||||
|
TUtFSk1OS0tIR0VHRkhEQ0NGRENBPj89PT87PDs4Ojw4OTo4Njk9QUxZZG1vb3By
|
||||||
|
cnFzcnR2fH99eHh7gISHjJKJjpGRk5WSkpKOiomIgHx0cm5vcXV+hIeLjo+SlZiY
|
||||||
|
mJWUlZmSjIJ4cG1jVE5NTkxIQ0ZMVFhXVldUVldYXWBiX19gXFxbWlhXU1FPTk1L
|
136
test/search_test_data/0002n.pat
Normal file
136
test/search_test_data/0002n.pat
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
TUxOT1JVUFNUVlVRT1VYWVdXUlJUT1FPU1VPT01PUE9WVlFSUFJRTkxKTU1PTEtJ
|
||||||
|
R0JDR0RDQEBBQD8/PDs/PD0+Pz44NzY1NjY5ODw5OT08Nzk5ODs8QUNBQj9BQUND
|
||||||
|
QklLSk5KSU9TXlhLT0xWUlFaVFdMTVdVW1VgWVdWXV9dWFtWUlFSTkVERTk1NTUz
|
||||||
|
MzUzNjU0ODg1ODY2Nzk6PTo6P0NETE1JR1RSTFBISkpKVVVLSUpUTU5STVZRVFpT
|
||||||
|
Vk5XXGBYUFhVWFJTV19kXVdVUFdVVlZUW1xbWlhZV1pcWE9TWlRWWVlXUE1MTlJD
|
||||||
|
PDo8Ozo+P0pOTVhWVFJWW15oYFxbXlpUVlpZXFhYVVdXUFlcYFhUVFdaW1RQXVxc
|
||||||
|
XltXUVBSTU1RUVRYVVNNSU1RUFFWVFFST05QUk9OSU5QTk1KS1BVSkxLTE5LT1RO
|
||||||
|
VlRZWlZYVE1FRkVHR0ZLSU9LTlFOXWaJo7CspZ2WlZOJfXFmYmFqdG9eS0E+OTk4
|
||||||
|
ODtBQTw9Ojg5PD5EQT8/P0BAPDc6OEE+Pzo+QENAPDtBQENDRkNDR0A6QEQ8ODU0
|
||||||
|
MTQ3NTg3Mzc2NDg0OTs/RUpTS05JT1xYWVlUXFZWVVtdWVlXUE5TUlJQT1BUVlZR
|
||||||
|
VFVYW1NRTkxMUlZUUEtMTk9PTE1MSERESUpLSkxJRklJSUtLRkRJSEVCRENERUZE
|
||||||
|
QkNBQ0JEQ0FAPjk6PDo3OTc3ODU2ODY2NTc+Rk9YYmdqaGhna3B3e3x+gYGBgYaH
|
||||||
|
iYuKi4uKioWCfXdwbmpnaWlsb3eCiIuMjYmJjo6SkJCTl5ORjIaBfnZnVEc/Ojo6
|
||||||
|
ODo7P0RJSkxPUlVWWVhWVlVSVFFRT05JRkVARD5BPkBCRERDQ0ZGRUdFSUpKSkpK
|
||||||
|
SklOS0xNTkxOT05MS0tMTk9NT1ZWU1dZWl1eXWJkZ2hqbm91dXV4fH5/gYB/gYOC
|
||||||
|
hYmGiIiHh4iGh4qLi4qMjY2Li4uLjZKTlpeWlpSPjo+SkZOQkpGRlZiXlpaZmZuZ
|
||||||
|
mZibl5mZmJiampual5aYnKCpr7KqmImGiJWosbzAvLu5u7i1tbGwsbKzt7a8vcC/
|
||||||
|
vL29vr6/v7q8vLq8vrq4ube1tLe3t7S0ta2ysrK1tKyginBfXVhTUlBOTVBMTU9M
|
||||||
|
S0tLSUpLSkhJSkdPT05KSUdNS0lJSE1LSkxKTk9MTUtNSk9OTUxPUU5NUE9OT0xM
|
||||||
|
Tk5QUVFQUU9QUVJSVFVSUlNTU1JRTlJTUFBSVFRSUlFTT09RUlBSUVNTUU9QUVNV
|
||||||
|
VVVVUVFSU1FVU1JSUFFSU1hUUVFPUVRQUVJRU1NUVVZYWFZWWlhYVFFVWFhXVlhW
|
||||||
|
WFhaWltbWF5bV1dYVlhbWFZYWVlaWVlYV1laWVpZV1taWVlaWlpaWVtcXV1cXF1d
|
||||||
|
YF9dYF5dXV1dYF5bXV1cWlxWV1dYV1ZWWFdYV1ZZXIO9ydPa3uHk5efo6el7enh5
|
||||||
|
ent8eHd1dnl2dnh6enl4eXdwZ1pMR0VFSkVEQz09Q0hKQ0A/P0I/PEJCQT4+PTpA
|
||||||
|
RURFQ0RHQ0RBPT5ARkhJSkxMTk1JS05QTklKTk5QUVNUU1FXU1ddWVVRUFFTU1JQ
|
||||||
|
UlBQT0tRVVVVU1JSUFJNSktPT0tJSUhHREVFQ0dEQkNAPj0+PTw7Ozs6OTw2Nzk4
|
||||||
|
ODg6PDs5OTg3Nzs4Ojw7Ozw9PURBQkQ/RktGS0tISUpRVU5RTUpTT1lTV1VOVlNc
|
||||||
|
WV1cWVddY1xdXllPT1JVT0pAODc1MzU5Njc6OTs3Njg2NTc7ODg4OTg+Q0dPUEpH
|
||||||
|
VVRMUUxRSkpUTklOSVNSTU1KV1RSWlFYVFRVWVdNUFJeVFRVYWFdXVZQUVVYV1VZ
|
||||||
|
VFdYWVhZXGVhVlRbW1pXUU1LTFBMTkhAOTg6OTk7Q1BSVVldWFpeXmFhY2VjXlNR
|
||||||
|
U1BXWFVVUVZYWFdWU1NTVVZaV09WWVlaWlNQTUtOUE1OUlhZVFFXUE1NUFBQTlFS
|
||||||
|
UFJWTU1OS0pRSkVJUFBNSkpNUEtPVFVXV1lXVldXU0hGRUdJSVBJSUhOVE9RWnWU
|
||||||
|
qauroZiVkYl8c2xmY2VrdWlSQTs6Ozg7OTw8Oz08PDw7Ozw7PTtAPj09Pj1BQUJA
|
||||||
|
OTo+QUQ9OD1FQUM+RUJCOzY9Q0E4ODU0NDY2NjQ0MzI1Njg4Oz1ESkpISkpTWlhY
|
||||||
|
W1ZZV1hTVldOUVNOTE5OUlFQVFlYU01XV1dWU09MSktOUlRTUU1PT0xQTklFR0ZL
|
||||||
|
TU1LS0dHR0dJSkpGRUNGSExHQ0RDREVBQD9APz5AOzs+QD88Pjw4NjY0Njc5Nzg7
|
||||||
|
QUpTXmRmaGdoaGxwdHp7fXmBh4eHhoyQj5CNjYuJhYJ8dnN1b2xtbGtze4SJjI6M
|
||||||
|
iImOj5KUlpWVk5GQi4B3a11RRj5APkFAQUFCSEpLTVBQU1hYWFZWV1NRUlBQTkxJ
|
||||||
|
RkdDQT5AP0NDQkNARERJR0lJRkhHSUtQUE1MS0tNTExNTE1NT1FSUFBVVVVXWF1f
|
||||||
|
XmNjZGdsbG5zdXZ1dnt9f4CDg4F/goOFhYaGh4uHhoWJi4mKi4mIiouNjIuMkZGR
|
||||||
|
lpSUj5GQkpKSkpWTkpaXl5OVlpmbmpiYmZmZmJqWlZeYl5iZmp+jqrO5s6aTgXeB
|
||||||
|
mK64vby7urq9ure0srSztba1t7m9vsDDwr69vb+9uru+wL69vbi3tbSztbq1tLe4
|
||||||
|
rrOztrW1saylknplXFZUVVNPTU9PTk5NTU1NSkhISkpJR0lKS0lKUEpKS0xPTVBL
|
||||||
|
TUxKS01KTExMTkpPTktQUE5PT09QTU5NUFBSUlNST1BPT05ST05PUVFTVlJSU1NS
|
||||||
|
UlRTUVJTUVBRUU5RTlFSU1NQTk5NUFVTUlBSUVBRVFRTU1NSVFJQUlVUVlNUVFFS
|
||||||
|
UFNVU1JUVVVWVVZXV1VWV1dWVVVYWVhZW1pYWVtdXF5aW1hZWFZZWVhYWlpYV1dY
|
||||||
|
WFZXW1tZWFlYWVhWWVlZXFxcW11cXltcXltdXlxdX19dXl5bXVtbWFlYV1VXV1ZU
|
||||||
|
VlVVVVdgfLvJ0dre4eTm5+jp6nl7e3x7eHp6dnh5dnd4dXd4dnZ5cmlgUkhCQEJH
|
||||||
|
QEM/PkFCRERBQERDQz4/QkU7PD1CPkBBQUFAQEFDR0I9PENCR0dISEdJTklMT01P
|
||||||
|
UlFNUFBRUlJZVVVWV1ZUU1hSVFZVUlJTUlBRUVNTVFVSUFFOUE5NTExPTUtIREhH
|
||||||
|
RENDQkJFQj5APkE/Pz87Oj08Oz04Nzc4NzxBODQ1Nzc4Ozo6Ojg2OTs7Ozs+QT9D
|
||||||
|
SUdISEZGRkpQS01LRElHTEpLVVRaWVhZXFtZVlhgX1xXV1BVblVUSkA5NzQ1NDc1
|
||||||
|
NTQzNDQ0NDg1Njc2NTg7PD8+PkpJTUZNT0dPS1JNSFBLRkxIS0hLSk1UVFlgVl5X
|
||||||
|
UVJUVUxRT1ZVUlFZXVpWVFJTVllZV1dUVFtaWltfZl1VWFtcVlZVT0tTUElIR0Q5
|
||||||
|
NzY3Njk/SVJWWmxlWlxdWWBpYV9kV1JUUVJcWlhTT1NSV1pTVFNTVlVXVlZVWFJU
|
||||||
|
WlNPS01VVVpaWVVYV1VWUU5QTk5PUFVRTE1LS0xIRU5KSEpOTk1JR01MSVBVWlxT
|
||||||
|
VFhcWFpZTkdDQEFFS0VISElTUU9WYniWpqiooJeOhn92a2NgYGZwbV5JOzs/QkI7
|
||||||
|
ODs9OkA+PDw6OT1APj4+SDw6Oz4/QkA7O0A9Pz5CPDs8QTxDQkJJPzpBPzo8Ozg2
|
||||||
|
NzQ3NjczMjQ2Nzg7PT9HS0RJR01SUldSUE9OT01VWFJWVE5LTlFTUlBSVldSVFhW
|
||||||
|
VFJWUVBNTEhLTFJUTExNS05OSUZITE1LS0pKT0pGREVGRkdIRklKSUlERURCQ0NC
|
||||||
|
Q0E+PDk9QD9BPzw6ODo4OTo9Ojg5PUdQW2VqamlrbWttcnd6fH19fYKDiI2Ojo2N
|
||||||
|
jo6LjIiIhX58eXVzcW9sb3d/hIyOkI+Lio6QkZOYlpSTjYuHgXJkWE1IRD89QEJF
|
||||||
|
RUZMT0xPUVNUVlhaW1lXVVNSUlJPTUtNS0dDQUJEQkJDRUZGR0hFR0dHQ0dHSEtI
|
||||||
|
SEtJS05LS0xSUVNQTlFUUlVZWFlcXWFlZ2hsbW9zcnV8fH9+fX+AgYGBg4SEg4KD
|
||||||
|
hYOCh4eHh4eJi4qKi4uOjI2KjpGSlZWUmZaSkpeWkI6TmJWYmpiXmJiampuXnJmY
|
||||||
|
lpaZmJqYmZmbnJ2jrLGwsbSwopSDfIeXrLu/vr28urq4s7OzsrK0trW3ubu8v8G/
|
||||||
|
v7++vr27ur27vLy7ubW2uby7t7e1ube1tbe2tLW0sa+mmIFmWldXUlBRT0xOS0xO
|
||||||
|
TVJPTUtKR0lKTEpKTUpJSUlLTUxJTE1PUExJS0tNS0xOTU5MS0xLS09PUVFTUE9R
|
||||||
|
UFNSU1FRVFJNT09OTlBQUlNSUVBRT1JUVFFPUVRUUVNRUE5QUVFSUFFPSk5RUE9P
|
||||||
|
UVNTVlFRTFBPUVJSUlJRT09SUlBQUE9RUlJTVVVTVFVWV1ZYWFZYV1hVVVRTV1ta
|
||||||
|
W11bWVxaXV1aWlpcWllZWllaXV5bV1dXWFpZWldXWVpZVlVXWVlbXFxaXF9cX11f
|
||||||
|
XFxcX15iYWBdXFhaW1pfXFtZV1RWVllXU1NXW2Z9usjT2d/h4+bn6OnpeXp7enl7
|
||||||
|
d3t7enl6eHp4eHl1dG9rZFtRSkdDQkBAQUY/PEVESUREREM9QUFEQUVBPT9BPT8/
|
||||||
|
Pz8+QT5BRENHQkNFRkhJS0xNTkxQTE1SU1NQUlNRUlVWVVVZWlZVU1VWU1ZWVFJQ
|
||||||
|
VlJPUFNXWFZVU1RUUFFPTkxISEdJTEpGREJCQUBAQENHQj07PTo8OzU5Nzc4ODg3
|
||||||
|
Nzg1ODk4ODc5Ozg6ODk3OTk4PD5FQj5AQEBFREU/QlFPSklIR0dHSkxUU1xZUVVZ
|
||||||
|
YFhPU2BaV1RYUU9UWFZKQDo3NzI0NTAyNjQ0Ozg4Njc2Nzk5ODw6Ozo+S0ZLRUdF
|
||||||
|
Q1RMWlVMUU9KT0pPTFVWSlVTVFtTWlNUVlJSTFNOUlRQSlRUWVdaWVVSUldZWlVT
|
||||||
|
U1dUU1pdXFZXW15VVVVOTldSTUdHRzo2NzU2OTk+TV1eYmJYX11aYGleX2lYTVJR
|
||||||
|
Vl5gXFhRUVNYXFJSWl1ZVlFWWlJSU1JcVVhTTlhYWFNTU1lYVVhSTU9RUVRTT05F
|
||||||
|
SEhJRk9NS01OTU9KS1FJTFFRUlNUV1FTV1xdX1lRSERBQkJHRkpJRVJRU1dVYnqW
|
||||||
|
pKekno+Jg3pybWhkZW1yZ1BEPDw+PTs3PDpEQ0E9Ozs7PDs/PEdCOjk9Oz1AQkA9
|
||||||
|
QEFEQj06Ojw7PT9ASUhAPEFCPDg4OTczNDM2NDQ1MzU2ODk6PD5FRk1JUE5WXlJU
|
||||||
|
UkxMTFVVT1BSUFRVVk5ISlNVVVRWWFRUVltYWE9LTUtKSkxJSUhLTU9NSUlMTkxI
|
||||||
|
TU9NR0NHSElLS0xISkhKRkNBQ0RCREJCQz49PDtAPjw6ODg5PDs5Ozg2OkBLWGNo
|
||||||
|
am1tbWtubXB1enp7e36Bg4aGiZKRjo2NjY2LiIiFhoKCd3Vua25vdH2DjI6NjIyO
|
||||||
|
kpGQkpOVko+NiYN4aV5XU01LSUI+PUNHTFFSU05RUlVUWVtcXFZUUlFUU1FPTkxK
|
||||||
|
R0ZCQUBAQUFEQz5CR0pIR0hESUhHRElKSklLS05MUFJVU1JRU1VaWFxdX19iY2lr
|
||||||
|
bW9ycnR3enp5e318fX9/gH6Cg4SFgIOFhoeGh4mMiouOjo6PjY+MjY2RlJKSlJuX
|
||||||
|
lZSUlZaQkpKWl5qTk5aYmpqbm5yampyam5mWl5uenZ+lqK2ytby9tqmcmJiRjJit
|
||||||
|
uL6/vru6uLKuq62vs7a2t7e6u73BwcHAwcG/vcC9vLm4u7e4t7i4ur29urq4tre6
|
||||||
|
uLa5trWzs62onohtXFVUVFJRT01NS0tKS05RS0tKS0xPTklJS0pJSUdLTEtJTEpO
|
||||||
|
S0tHSUpNT05QTk5LS0xQTlBPUFJRTVBRTk9OT05PUlJPUlBQTk9QUFFRT1FRVVNU
|
||||||
|
VFRTUlFWU1JQU1JRUFNVV1RPT1BRT1*SUVNUU1JOTlBPUFBQU1RSUVBSUVNSUVNR
|
||||||
|
UVNVVFRTVVRWVFJTVlhXWVdXU1NTWFtbWl5dXFlZWFhZWFxYVlpYWFlbWVpZWVZX
|
||||||
|
V1dYWVhYWFdXVVRZW1pZWlxdW1peXl1cXGBgX19gYV9fW1pZW1lcW1hWVFVXVVlW
|
||||||
|
U1NVaoS8ytPa3uLk5+jo6el4eXh1eXh9eHt7e3t4eHZ1eHh0cm5jWEtLTEY/PTs8
|
||||||
|
P0NGSklGREVBOz0+RD9BRENAPkE/Oj0+P0A9Pz0+Q0NCQkRJSUlKSUtMTEpLTFBU
|
||||||
|
VlVUVlZSWVteXFpYU1RXWFlVWFlXV1VTVVJPUlZaVldTUVJRUVFOUE1KTE1LSElF
|
||||||
|
QUVEQkVCRUNERD8/Pjs8QDw6Ojo6Ozw5Nzk5PDc2NDQ4Ojg6OTk4Ojc4PEQ7Oj0/
|
||||||
|
PUNCRkNBSUtHSERJTEdKR1BLUVlVV1ZiV1BLU1JVVVZWU1RbWVBJQzo9NzY3NzYy
|
||||||
|
Mjc3ODg0MzU3OTk/Pjo8Oz1ERk9FRkVJSklXUkxWUVBRSlFPV1ZHTU9SXlVdVVdc
|
||||||
|
VlZMUk1QWVJRUFNZWF5eWU9PU1VWVFRSWFBPVllbWlZYWVdUVFFYXFhTUkxKQTo0
|
||||||
|
MjQ1OT5DVFhPV1paYFtgX15gX1FPUlRUWltbVlNPUVdWUlhXXVZVVldaVlNWVllZ
|
||||||
|
VFNPTVNRTVFPUlNUUVVUUlhVU1ZRS0lLRk1LSFFPTVFNTUpLT01LUlRMTVNVU1BU
|
||||||
|
V1tiWFVQSUNDQEVDSEhHVVJYWlBYXn6Ypqiil4qBfHp4cGttcHNtYFBDOz47Ojo3
|
||||||
|
OT07ODo7Oz88OjxAREA8Pj07OjxBQTw4PUFEQTxAPTtBRUVGR0U+QEI+ODUzMzc2
|
||||||
|
Njc4ODQxNDY3OTs8P0RKR0hSTlVfVVtRT09RU1VSUVJTU1JQS05OTVJXVVZUUVNY
|
||||||
|
VVRSTUxOSUtMSktKTEpJTEpKRkdLTE1NT01NSklJSktOTkpGREdGQUFERUREREI9
|
||||||
|
Pj4/Ozc5ODo5Njc6OTs5NzpBSlhja21vb3RxcHBucnp9eXl6fH+EhIWGjo2Njo+N
|
||||||
|
j4+MiYuLhH54cm5tb3BzfYaLjo6MjpKSkpORlJeWkpCHfnNrYVdWVVRMQj0/RE9V
|
||||||
|
UVJQUVFRVFtcXF1dXFlWVlZXV1FRTk9NS0VDQ0FBQUFAP0FER0dHR0dHSUhKSkxL
|
||||||
|
TEpJTlJOUFFUVlNWVltcYGBfZGhnaW5wcnR2dXh6eXt8f4GBgoKAg4GBgoODgoSE
|
||||||
|
iIiHio6Ni4+Sk46KjY6Qk5WVkpGUlJOSlpKSlJWTkpOYmJiYmZial5iZm5mZmpye
|
||||||
|
nZ+foKGip7Cyt7e5vLyznpKcn5aVorO5wcC/wLm2sa2rrK+zuLa4uL2/v768vMDA
|
||||||
|
wsG+wL68vra1tLK1tri8vbi6ubi2tre3tra1tbW4trGroY1tW1hUVFNNTk5KSktP
|
||||||
|
T0tLSkpMSktNTExLS0tLSkxKSUlMTUtLSk5JSE1OTk9MTE9RT0xNUFBRU1BPTU1P
|
||||||
|
UFBTUlFPUlFOUVNRUFFRUU9OUFFTU1NTUlNUVFJTUU5QUlJUVVRUU1ZST1BPUFFS
|
||||||
|
UVBOUVJPUFJSUFJRU1NRUFFSVFNSVFNUVFFRU1RXVlVXVFlYWFhZWFhVWFZUWFdX
|
||||||
|
XV1cWFdYWVdaWFdaVVVaWVlaWVdaWVlYVVdaWVlXWFlbWFdYWVpdW1xcXlpbX2Fj
|
||||||
|
YmBhYV9fX15cXl9aWFlVUFZWV1lYWVlXU1V#orzJ0tre4eTm5+jq6nl3d3l4d3h6
|
||||||
|
ent8fHh2dXN1d3NxbGFUSkdGSEM7Pj89QUhJRkZFQ0RFQ0JCQj09PTg8PUE7Oj4+
|
||||||
|
Qz0/QEFDQkVHR0pJSUxLTU1MTExLT1FSVFNTVVRVWFdXV1ZRUlNWVlVXWFlXWlta
|
||||||
|
VFZXWlxZV1VTVVBTUU1NTEtNS05MR0pMSEVER0ZISEVERD4+Ozs6Ozs6OTk6Ojc1
|
||||||
|
NTY5ODY2Njg2NzY4ODk3PDo4Pjw8PD9CRUFBPT5GRkVLTEZLTVFKSkxSW1daV11Z
|
||||||
|
SlJWVlNSV1pUU1dXVlZQQjo7OTU1NDMyNjc0NTZINzc3OTo8PT07QUJDUkpOS0hN
|
||||||
|
R1RRTlRQTlFIUFJVVEhSUVJgV1ZSWmFeYFJVTk5VUlJQV1lUVVZQSk5OUVZYVFBP
|
||||||
|
UFNUWV1XUlRZWFlXVFVcXlpWWFBCOTIyMzc2PUNNV01TWlpbW1paXl1VVFZXVVZZ
|
||||||
|
V1lcUk1OU1BVXVlaVlNTUVNYVVVbUk9VT05JTE9SUU9QUVZVUlNVWFlUS05LTFFU
|
||||||
|
V09SUFNSUVRNSkpNUk5OV1FNVFpSTlRcYVxYW1FKQ0JER0NFR0hTTFFUTlVWbYma
|
||||||
|
paOelImBfXx7dnRxcXBpWkY9Oj1COTQ5Ozs7QTk6Pzw7Ozs/QEJDPDo6PkBFPjtA
|
||||||
|
QkRFQjk6PUJGREZEQkFCRj04MzQ1ODk1NTM5NzQ0NTk6Oj49P0JFSFRRWFlSXFNS
|
||||||
|
VlZXVVRTU1ZTUFNNTU5PUFRUV1lRTk5SU09MTU5PUVBKS01MSkhIS0pJR0hDR0tL
|
||||||
|
TUtFSk1OS0tIR0VHRkhEQ0NGRENBPj89PT87PDs4Ojw4OTo4Njk9QUxZZG1vb3By
|
||||||
|
cnFzcnR2fH99eHh7gISHjJKJjpGRk5WSkpKOiomIgHx0cm5vcXV+hIeLjo+SlZiY
|
||||||
|
mJWUlZmSjIJ4cG1jVE5NTkxIQ0ZMVFhXVldUVldYXWBiX19gXFxbWlhXU1FPTk1L
|
Reference in New Issue
Block a user