Essentially, you can shift the window of the length of your word above your input and count the number of each letter in the window. When a letter is counted in your sliding window matching the letters of your word, you have a match.
Let the word length be n , and your current position is curr . Create an array or vector , windCounts length 26. The record windCounts[i] stores the number of occurrences of the letter i th of the alphabet, visible from the position curr - n - 1 , on curr .
What you do is move curr and update the windCounts array by decreasing the letter dropped out of the back of the sliding window and increasing the number of letters appearing in the front sliding window. (Obviously, to curr > n , you are only increasing, you are simply expanding your sliding window to the length of your word.)
In C ++, you can use vector to count the letters in a word and to count the letters in a sliding window and just use vector::operator== to do the equality.
Edit: O(N) algorithm, where n is the length of the text to search. This can be seen from the code below, where the body of the loop is executed for each letter that you insert into the window.
#include <string> #include <vector> #include <algorithm> // for_each using std::string; using std::vector; #include <iostream> int main(int argc, char* argv[]) { const string text = "forxxorfxdofr"; const string word = "for"; // Counts of letters in word vector<int> wordCounts(256); // optimization: cut down from 256 to 26 std::for_each(word.begin(), word.end(), [&] (char c) { wordCounts[c]++; } ); // Current position of end of sliding window string::const_iterator curr = text.begin() + word.size(); // Initial sliding window counts vector<int> windCounts(256); std::for_each(text.begin(), curr, [&] (char c) { windCounts[c]++; } ); // Run sliding window over text int numMatches = 0; while (1) { numMatches += wordCounts == windCounts; if (curr == text.end()) { break; } windCounts[*(curr - word.size())]--; windCounts[*curr]++; ++curr; } std::cout << numMatches << "\n"; return 0; }
Tooone
source share