1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <set>
struct Sequence
{
Sequence(char const* pPos, size_t pLength) : pos(pPos), length(pLength) {}
char const* pos;
size_t length;
};
size_t commonPrefixSize(char const* s1, char const* s2)
{
size_t result = 0;
while (*s1 != '\0' && *s1 == *s2) {
++s1;
++s2;
++result;
}
return result;
}
std::ostream& operator<<(std::ostream& os, Sequence const& s)
{
os.write(s.pos, s.length);
}
bool isLonger(Sequence const& l, Sequence const& r)
{
return l.length > r.length;
}
struct SequenceSetLess
{
bool operator() (Sequence const& l, Sequence const& r)
{
int s = strncmp(l.pos, r.pos, std::min(l.length, r.length));
return (s < 0) || (s == 0 && l.length < r.length);
}
};
bool isBefore(char const* l, char const* r)
{
return strcmp(l, r) < 0;
}
void showRepeatedSequences(std::ostream& os, char const* s)
{
std::vector<char const*> substrings;
for (; *s != '\0'; ++s) {
substrings.push_back(s);
}
sort(substrings.begin(), substrings.end(), isBefore);
std::set<Sequence, SequenceSetLess> sequences;
for (std::vector<char const*>::iterator i = substrings.begin();
i+1 != substrings.end();
++i)
{
size_t prefixSize = commonPrefixSize(*i, *(i+1));
if (prefixSize > 0) {
sequences.insert(Sequence(*i, prefixSize));
}
}
std::vector<Sequence> seqTable(sequences.begin(), sequences.end());
sort(seqTable.begin(), seqTable.end(), isLonger);
std::copy(seqTable.begin(), seqTable.end(),
std::ostream_iterator<Sequence>(os, "\n"));
}
int main(int argc, char* argv[])
{
for (++argv; *argv != NULL; ++argv) {
std::cout << "\n" << *argv << " repeated substrings:\n";
showRepeatedSequences(std::cout, *argv);
}
} |
Partager