Not So Naive Algorithm
Definition:
The Not So Naive Algorithm is an improvement over the naive string matching algorithm that optimizes character comparisons by utilizing information from previous matches. It reduces unnecessary comparisons by identifying patterns in the text and using this information to skip redundant checks.
Characteristics:
-
Smart Comparisons:
- Efficient comparison ordering
- Skip redundant checks
- Pattern analysis
-
Pattern Preprocessing:
- Pattern structure analysis
- Match history utilization
- Optimization setup
-
Left-to-Right Scanning:
- Linear text traversal
- Optimized comparison sequence
- Early mismatch detection
-
Memory Efficiency:
- Minimal additional storage
- Constant space overhead
- Simple implementation
Time Complexity:
-
Preprocessing:
- Where m is pattern length
- Pattern analysis
- One-time computation
-
Searching:
- Where n is text length
- Better average case
- Optimized comparisons
Space Complexity:
- Space Usage:
- Constant extra space
- No preprocessing storage
- Pattern storage only
C++ Implementation:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class NotSoNaiveAlgorithm {
private:
// Check if pattern has periodicity
bool hasPeriodicPattern(const string& pattern) {
int m = pattern.length();
for (int i = 1; i <= m/2; i++) {
bool isPeriodic = true;
for (int j = i; j < m; j++) {
if (pattern[j] != pattern[j - i]) {
isPeriodic = false;
break;
}
}
if (isPeriodic) {
return true;
}
}
return false;
}
public:
vector<int> search(const string& text, const string& pattern) {
vector<int> matches;
int n = text.length();
int m = pattern.length();
if (m == 0 || m > n) return matches;
bool isPeriodic = hasPeriodicPattern(pattern);
int i = 0; // text position
while (i <= n - m) {
int j = 0; // pattern position
// First character comparison
if (text[i] == pattern[0]) {
// If pattern is not periodic, use optimized comparison
if (!isPeriodic) {
// Compare last character early
if (text[i + m - 1] != pattern[m - 1]) {
i++;
continue;
}
// Compare remaining characters
j = 1;
while (j < m - 1 && pattern[j] == text[i + j]) {
j++;
}
if (j == m - 1) {
matches.push_back(i);
}
} else {
// Use standard comparison for periodic patterns
j = 1;
while (j < m && pattern[j] == text[i + j]) {
j++;
}
if (j == m) {
matches.push_back(i);
}
}
}
i++;
}
return matches;
}
// Advanced search with additional optimizations
vector<int> advancedSearch(const string& text, const string& pattern) {
vector<int> matches;
int n = text.length();
int m = pattern.length();
if (m == 0 || m > n) return matches;
// Additional optimization: character frequency check
vector<bool> patternChars(256, false);
for (char c : pattern) {
patternChars[c] = true;
}
int i = 0;
while (i <= n - m) {
// Skip if character not in pattern
if (!patternChars[text[i]]) {
i++;
continue;
}
// Pattern matching with optimizations
if (text[i] == pattern[0]) {
bool mismatch = false;
// Check last character early
if (text[i + m - 1] != pattern[m - 1]) {
i++;
continue;
}
// Check middle character
int mid = m / 2;
if (text[i + mid] != pattern[mid]) {
i++;
continue;
}
// Check remaining characters
for (int j = 1; j < m - 1; j++) {
if (j != mid && pattern[j] != text[i + j]) {
mismatch = true;
break;
}
}
if (!mismatch) {
matches.push_back(i);
}
}
i++;
}
return matches;
}
};
// Demonstration class
class NotSoNaiveDemo {
public:
static void demonstrateAlgorithm() {
NotSoNaiveAlgorithm algo;
// Example 1: Basic pattern matching
string text = "ABCABCABCABC";
string pattern = "ABCABC";
cout << "Text: " << text << endl;
cout << "Pattern: " << pattern << endl;
vector<int> matches = algo.search(text, pattern);
cout << "\nBasic search - Pattern found at positions: ";
for (int pos : matches) {
cout << pos << " ";
}
cout << endl;
// Example 2: Advanced search
matches = algo.advancedSearch(text, pattern);
cout << "Advanced search - Pattern found at positions: ";
for (int pos : matches) {
cout << pos << " ";
}
cout << endl;
// Example 3: Non-periodic pattern
text = "ABCDEFGABCDEFG";
pattern = "DEFG";
cout << "\nText: " << text << endl;
cout << "Pattern: " << pattern << endl;
matches = algo.search(text, pattern);
cout << "Pattern found at positions: ";
for (int pos : matches) {
cout << pos << " ";
}
cout << endl;
}
};
int main() {
NotSoNaiveDemo::demonstrateAlgorithm();
return 0;
}
Key Features:
-
Optimized Comparisons:
- Smart character ordering
- Early mismatch detection
- Pattern-based optimization
-
Pattern Analysis:
- Periodicity detection
- Character frequency
- Pattern structure
-
Simple Implementation:
- Minimal overhead
- Easy to understand
- Efficient execution
Applications:
-
Text Processing:
- Simple pattern matching
- Document searching
- Content analysis
-
Data Filtering:
- Basic text filtering
- Pattern detection
- Content validation
-
String Searching:
- Simple searches
- Pattern location
- Text analysis
-
Educational Use:
- Algorithm teaching
- Pattern matching concepts
- Optimization techniques