Cod sursa(job #908307)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 9 martie 2013 00:54:27
Problema Potrivirea sirurilor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 kb
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>

#define MAXN 2000005

using namespace std;

int SkipTable[MAXN];

void BuildSkipTable(const string& sPattern)
{
    int iPatternLength = sPattern.length();
    int iCandidateIndex = 0;

    for (int iPatternIndex = 2; iPatternIndex < iPatternLength; ++iPatternIndex)
    {
        while (sPattern[iCandidateIndex] != sPattern[iPatternIndex-1] && iCandidateIndex > 0)
        {
            iCandidateIndex = SkipTable[iCandidateIndex];
        }

        if (sPattern[iCandidateIndex] == sPattern[iPatternIndex-1])
        {
            ++iCandidateIndex;
            SkipTable[iPatternIndex] = iCandidateIndex;
        }
    }
}

template <typename Iter>
int kmp_search(const string& sPattern, const string& sText, Iter itOut)
{
    int iPatternLength = sPattern.length();
    int iTextLength = sText.length();
    int iPatternIndex = 0;
    int iTextIndex = 0;
    int iMatched = 0;

    while (iTextIndex < iTextLength)
    {
        while (sPattern[iPatternIndex] != sText[iTextIndex] && iPatternIndex > 0)
        {
            iPatternIndex = SkipTable[iPatternIndex];
        }

        if (sPattern[iPatternIndex] == sText[iTextIndex])
        {
            ++iPatternIndex;
            if (iPatternIndex == iPatternLength)
            {
                ++iMatched;
                if (iMatched <= 1000)
                {
                    *itOut = iTextIndex - iPatternLength + 1;
                    ++itOut;
                }

                iPatternIndex = SkipTable[iPatternLength-1];
            }
            else
            {
                ++iTextIndex;
            }
        }
        else
        {
            ++iTextIndex;
        }
    }

    return iMatched;
}

int main()
{
    string pattern;
    string text;
    vector<int> vMatches;
    fstream fin("strmatch.in", fstream::in);
    fstream fout("strmatch.out", fstream::out);
    
    fin >> pattern >> text;
    //cout << pattern << endl << text << endl;
    
    BuildSkipTable(pattern);
    const int iTotalMatches = kmp_search(pattern, text, back_inserter(vMatches));
    
    cout << iTotalMatches << "\n";
    ostream_iterator<int> itOut(cout, " ");
    copy(vMatches.begin(), vMatches.end(), itOut);
    cout << "\n";
    
    fin.close();
    fout.close();
    return 0;
}