Pagini recente » Cod sursa (job #964218) | Cod sursa (job #476453) | Cod sursa (job #1646825) | Cod sursa (job #599988) | Cod sursa (job #600622)
Cod sursa(job #600622)
# include <cstdio>
# include <cstring>
const char *FIN = "strmatch.in", *FOU = "strmatch.out";
const int MAX = 2000005, ALPHABET_SIZE = 2000005;
char needle[MAX], haystack[MAX];
int S[1005];
int badcharacter[ALPHABET_SIZE];
int * compute_prefix_func(char *p, int len)
{
int *pi = new int[len];
int k = 0;
pi[0] = k;
for (int q=1; q<len; q++) {
while (k>0 && p[k]!=p[q])
k = pi[k-1];
if (p[k] == p[q])
k++;
pi[q] = k;
}
return pi;
}
void prepare_badcharacter_heuristic(const char *str, size_t size, int result[ALPHABET_SIZE])
{
size_t i;
for (i = 0; i < ALPHABET_SIZE; i++)
result[i] = -1;
for (i = 0; i < size; i++)
result[(size_t) str[i]] = i;
}
/* result is array of size size+1 holding the strong suffix rule results
as described above */
void prepare_goodsuffix_heuristic(const char *normal, size_t size, int result[])
{
char *left = (char *) normal;
char *right = left + size;
char reversed[size+1];
char *tmp = reversed + size;
size_t i,j;
char test;
/* reverse string */
*tmp = 0;
while (left < right)
*(--tmp) = *(left++);
int *prefix_reversed = compute_prefix_func(reversed, size);
/* can't figure out how to handle first and last positions with the rest
its algorithm is slightly different */
//result of 0 will only be accessed when we find a match
//so it stores the good suffix skip of the first character
//(last in reverse calculation)
result[0] = size - prefix_reversed[size-1];
//The last value in the prefix calculation is always
//the same for a string in both directions
i = 1;
result[size] = 1;
while (prefix_reversed[i++])
result[size]++;
for (i=1; i<size; i++) {
test = 0;
for (j=i; j<size-1; j++) {
if (prefix_reversed[j] == i) {
test = 1;
if (prefix_reversed[j+1] == 0) {
test = 2;
break;
}
}
}
if (test == 1)
result[size-i] = size;
else if (test == 2)
result[size-i] = j+1 - i;
else
result[size-i] = size - prefix_reversed[size-1];
}
delete[] prefix_reversed;
}
/*
* Boyer-Moore search algorithm
*/
void boyermoore_search()
{
/* Calc string sizes */
size_t needle_len, haystack_len;
needle_len = strlen(needle);
haystack_len = strlen(haystack);
/** Simple checks */
if(haystack_len == 0)
return;
if(needle_len == 0)
return;
if(needle_len > haystack_len)
return;
/** Initialize heuristics */
int goodsuffix[needle_len+1];
prepare_badcharacter_heuristic(needle, needle_len, badcharacter);
prepare_goodsuffix_heuristic(needle, needle_len, goodsuffix);
/** Boyer-Moore search */
size_t s = 0;
while(s <= (haystack_len - needle_len))
{
size_t j = needle_len;
while(j > 0 && needle[j-1] == haystack[s+j-1])
j--;
if(j > 0) {
int k = badcharacter[(size_t) haystack[s+j-1]];
int m;
if(k < (int)j && (m = j-k-1) > goodsuffix[j])
s+= m;
else
s+= goodsuffix[j];
} else {
++S[0];
if (S[0] < 1001) S[S[0]] = s;//printf ("%d\n", s);//cout<<"Pattern found at "<<s<<endl;
s += goodsuffix[0];
}
}
}
int main (void) {
freopen (FIN, "r", stdin);
scanf ("%s %s", needle, haystack);
boyermoore_search ();
freopen (FOU, "w", stdout);
printf ("%d\n", S[0]);
for (int i = 1; i <= S[0] && i <= 1000; ++i)
printf ("%d ", S[i]);
}