Cod sursa(job #831754)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 9 decembrie 2012 05:08:00
Problema Potrivirea sirurilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.6 kb
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>

#define MAXN 2000005

using namespace std;

int BacktrackTable[MAXN];

void BuildBacktrackTable(const string& sPattern)
{   
    BacktrackTable[0] = -1;
    BacktrackTable[1] = 0;
    int iPatternIndex = 2;
    int iCandidateIndex = 0;
    
    while (iPatternIndex < sPattern.length())
    {
        if (sPattern[iPatternIndex-1] == sPattern[iCandidateIndex])
        {
            ++iCandidateIndex;
            BacktrackTable[iPatternIndex] = iCandidateIndex;
            ++iPatternIndex;
        }
        else
        {
            if (iCandidateIndex > 0)
            {
                iCandidateIndex = BacktrackTable[iCandidateIndex];
            }
            else
            {
                BacktrackTable[iPatternIndex] = 0;
                ++iPatternIndex;
            }
        }
    }
}

int kmp_search(const string& sPattern, const string& sText, vector<int>& vMatches)
{
    int iTotalMatches = 0;
    int iTextIndex=0;
    int iPatternIndex=0;
    int iTextLength = sText.length();
    int iPatternLength = sPattern.length();

    while (iTextIndex < iTextLength)
    {
        if (sText[iTextIndex] == sPattern[iPatternIndex])
        {
            if (iPatternIndex == iPatternLength-1)
            {
                ++iTotalMatches;
                if (iTotalMatches <= 1000)
                {
                    vMatches.push_back(iTextIndex - iPatternLength + 1);
                }
                
                iPatternIndex = BacktrackTable[iPatternIndex];
            }
            else
            {
                ++iPatternIndex;
                ++iTextIndex;
            }
        }
        else
        {
            if (iPatternIndex > 0)
            {
                iPatternIndex = BacktrackTable[iPatternIndex];
            }
            else
            {
                ++iTextIndex;
            }
        }
    }
    
    return iTotalMatches;
}

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;
    
    BuildBacktrackTable(pattern);
    const int iTotalMatches = kmp_search(pattern, text, vMatches);
    
    fout << iTotalMatches << "\n";
    ostream_iterator<int> itOut(fout, " ");
    copy(vMatches.begin(), vMatches.end(), itOut);
    fout << "\n";
    
    fin.close();
    fout.close();
    return 0;
}