Cod sursa(job #831790)

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

#define MAXN 2000005

using namespace std;

int SkipTable[MAXN];

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

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

        ++iPatternIndex;
        
        /*if (sPattern[iPatternIndex-1] == sPattern[iCandidateIndex])
        {
            ++iCandidateIndex;
            SkipTable[iPatternIndex] = iCandidateIndex;
            ++iPatternIndex;
        }
        else
        {
            if (iCandidateIndex > 0)
            {
                iCandidateIndex = SkipTable[iCandidateIndex];
            }
            else
            {
                SkipTable[iPatternIndex] = 0;
                ++iPatternIndex;
            }
        }*/
    }
}

template <class OutputIterator>
int KnuthMorrisPratt(const string& sPattern, const string& sText, OutputIterator itOut)
{
    int iTextIndex = 0;
    int iPatternIndex = 0;
    int iTextLength = sText.length();
    int iPatternLength = sPattern.length();
    int iTotalMatched = 0;
    
    while (iTextIndex < iTextLength)
    {
        switch (sText[iTextIndex] == sPattern[iPatternIndex])
        {
            case 0:
            {
                if (iPatternIndex > 0)
                {
                    iPatternIndex = SkipTable[iPatternIndex];
                }
                else
                {
                    ++iTextIndex;
                }
            }; break;
            
            default:
            {
                if (iPatternIndex == iPatternLength-1)
                {
                    ++iTotalMatched;
                    if (iTotalMatched <= 1000)
                    {
                        *itOut = iTextIndex - iPatternLength + 1;
                        ++itOut;
                    }
                    iPatternIndex = SkipTable[iPatternIndex];
                }
                else
                {
                    ++iTextIndex;
                    ++iPatternIndex;
                }
            }
        }
    }
    
    return iTotalMatched;
}

int main()
{
    string sText, sPattern;
    vector<int> vMatched;
    fstream fin("strmatch.in", fstream::in);
    fstream fout("strmatch.out", fstream::out);
    
    fin >> sPattern >> sText ;
    //cout << sText << endl << sPattern << endl;
    
    BuildSkipTable(sPattern);
    
    int iTotalMatched = KnuthMorrisPratt(sPattern, sText, back_inserter(vMatched));
    
    fout << iTotalMatched << "\n";
    ostream_iterator<int> itOut(fout, " ");
    copy(vMatched.begin(), vMatched.end(), itOut);
    fout << "\n";
    
    fin.close();
    fout.close();
    return 0;
}