Cod sursa(job #879015)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 14 februarie 2013 21:41:11
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb
#include <fstream>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <vector>

#define MAX_MATCH_POS_RECORDED 1001
#define MAXN 2000002

using namespace std;

int SkipTable[MAXN];

void BuildSkipTable(const string& sPattern)
{
    const int iPatternLength = sPattern.length();
    int iCandidateIndex = 0;
    
    for (int iPatternIndex = 2; iPatternIndex < iPatternLength; ++iPatternIndex)
    {
        while (sPattern[iPatternIndex-1] != sPattern[iCandidateIndex] && iCandidateIndex > 0)
        {
            iCandidateIndex = SkipTable[iCandidateIndex];
        }
        
        if (sPattern[iPatternIndex-1] == sPattern[iCandidateIndex])
        {
            ++iCandidateIndex;
            SkipTable[iPatternIndex] = iCandidateIndex;
        }
    }
}

template <typename OutIter>
int KnuthMorrisPratt(const string& sText, const string& sPattern, OutIter itOut)
{
    const int iTextLength = sText.length();
    int iTextIndex = 0;
    const int iPatternLength = sPattern.length();
    int iPatternIndex = 0;
    int iTotalMatches = 0;
    
    while (iTextIndex < iTextLength)
    {
        while (sText[iTextIndex] != sPattern[iPatternIndex] && iPatternIndex > 0)
        {
            iPatternIndex = SkipTable[iPatternIndex];
        }
        
        if (sText[iTextIndex] == sPattern[iPatternIndex])
        {
            ++iPatternIndex;
            if (iPatternIndex == iPatternLength)
            {
                iPatternIndex = SkipTable[iPatternLength-1];
                ++iTotalMatches;
                if (iTotalMatches <= 1000)
                {
                    *itOut = iTextIndex - iPatternLength + 1;
                    ++itOut;
                }
            }
            else
            {
                ++iTextIndex;
            }
        }
        else
        {
            ++iTextIndex;
        }
    }
    
    return iTotalMatches;
}

int main()
{
    string sText;
    string sPattern;
    vector<int> vMatchPositions;
    fstream fin("strmatch.in", fstream::in);
    fstream fout("strmatch.out", fstream::out);
    
    ostream_iterator<int> itOut(fout, " ");
    
    fin >> sPattern;
    fin >> sText;
    
    vMatchPositions.reserve(MAX_MATCH_POS_RECORDED);

    BuildSkipTable(sPattern);
    const int iTotalMatches = KnuthMorrisPratt(sText, sPattern, back_inserter(vMatchPositions));
    
    fout << iTotalMatches << "\n";
    copy(vMatchPositions.begin(), vMatchPositions.end(), itOut);
    fout << "\n";
    
    return 0;
}