Cod sursa(job #832253)

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

#define MAXN 2000005

using namespace std;

typedef unsigned int uint32;

uint32 uHashPolynomial[MAXN];

template<typename OutputIter>
int RabinKarp(const string& sPattern, const string& sText, OutputIter itOut)
{
    int iTotalMatched = 0;
    int iPatternLength = sPattern.length();
    int iTextLength = sText.length();
    
    uint32 a = 1664525;
    uint32 iPatternHash = 0;
    uint32 iSubTextHash = 0;
    
    uint32 current = 1;
    for (int i=iPatternLength-1; i>=0; --i)
    {
        uHashPolynomial[i] = current;
        iPatternHash += (static_cast<uint32>(sPattern[i]) * uHashPolynomial[i]);
        current *= a;
    }

    for (int i=iPatternLength-1; i>=0; --i)
    {
        iSubTextHash += (static_cast<uint32>(sText[i]) * uHashPolynomial[i]);
    }
    
    if (iSubTextHash == iPatternHash)
    {
        ++iTotalMatched;
        *itOut = 0;
        ++itOut;
    }
    
    for (int i=iPatternLength; i<iTextLength; ++i)
    {
        iSubTextHash -= (static_cast<uint32>(sText[i-iPatternLength]) * uHashPolynomial[0]);
        iSubTextHash *= a;
        iSubTextHash += (static_cast<uint32>(sText[i]) * uHashPolynomial[iPatternLength-1]);
        
        if (iSubTextHash == iPatternHash)
        {
            ++iTotalMatched;
            
            if (iTotalMatched <= 1000)
            {
                *itOut = i-iPatternLength+1;
                ++itOut;
            }
        }
    }
    
    return iTotalMatched;
}


int main()
{
    vector<int> vMatched;
    string sPattern, sText;
    fstream fin("strmatch.in", fstream::in);
    fstream fout("strmatch.out", fstream::out);
    
    fin >> sPattern >> sText;
    //cout << sPattern << endl << sText << endl;
    
    const int iTotalMatched = RabinKarp(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;
}