64,676
社区成员
发帖
与我相关
我的任务
分享
// StringMatch.hpp
#ifndef STRING_MATCH_HPP
#define STRING_MATCH_HPP
#include <boost/dynamic_bitset.hpp>
#include <iostream>
class Matcher
{
struct DummyAction
{
void operator()(const std::string& s, size_t pos, size_t length) const
{
}
};
public:
class State
{
friend class Matcher;
private:
size_t pos;
boost::dynamic_bitset<> D;
};
Matcher(const std::string& pattern)
{
pattern_length = pattern.size();
for (int i = 0; i < UCHAR_MAX; ++i)
B[i].resize(pattern_length);
for (size_t i = 0; i < pattern_length; ++i)
B[(unsigned char)pattern[i]].set(i);
}
template <typename MatchAction>
int Match(const std::string& s, MatchAction action)
{
int result = 0;
boost::dynamic_bitset<> D(pattern_length);
for (size_t i = 0; i<s.length(); ++i)
{
D <<= 1;
D.set(0);
D &= B[(unsigned char)s[i]];
if (D.test(pattern_length - 1))
{
action(s, i - pattern_length + 1, pattern_length);
++result;
}
}
return result;
}
int Match(const std::string& s)
{
DummyAction action;
return Match(s, action);
}
int FirstMatch(const std::string& s, State& state)
{
state.D.resize(pattern_length);
state.pos = 0;
return NextMatch(s, state);
}
int NextMatch(const std::string& s, State& state)
{
for (; state.pos < s.length(); ++state.pos)
{
state.D <<= 1;
state.D.set(0);
state.D &= B[(unsigned char)s[state.pos]];
if (state.D.test(pattern_length - 1))
{
++state.pos;
return (int)(state.pos - pattern_length);
}
}
return -1;
}
private:
boost::dynamic_bitset<> B[UCHAR_MAX + 1];
size_t pattern_length;
};
#endif//STRING_MATCH_HPP
// test.cpp
#include "StringMatch.hpp"
void ReportMatch(const std::string& s, size_t pos, size_t length)
{
std::cout << s.substr(pos, length) << '\n';
}
int main()
{
const std::string pattern("announce");
const std::string s("announceannounceannounceannounceannounce");
Matcher m(pattern);
m.Match(s, ReportMatch);
Matcher::State state;
for (int n = m.FirstMatch(s, state); n >= 0; n = m.NextMatch(s, state))
std::cout << s.substr(n, pattern.length()) << '\n';
}