Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have been stuck for some time on which is the fastest string search algorithm, heard many opinions, but in the end I'm not sure.

I have heard some people saying that the fastest algorithm is Boyer-Moore and some saying that Knuth-Morris-Pratt is actually faster.

I have looked up for the complexity on both of them but they mostly look the same O(n+m). I have found that in the worst case scenario Boyer-Moore has an O(nm) complexity compared to Knuth-Morris-Pratt which has O(m+2*n). Where n=length of text and m=length of pattern.

As far as I know Boyer-Moore has a linear-worst case-time if I would use the Galil Rule.

My question, Over all which is actually the fastest String search algorithm (This question includes all possible sting algorithms not just Boyer-Moore and Knuth-Morris-Pratt).

Edit: Due to this answer

What I'm exactly looking for is:

Given a text T and a pattern P I have to find all the appearances of P in T.

Also the length of P and T are from [1,2 000 000] and the program has to run under 0.15 sec.

I know that KMP and Rabin-Karp are enough to get a 100% score on the problem but I for one wanted to try and implement Boyer-Moore. Which would be best for this type of pattern search?

share|improve this question
5  
When you tested these out in your language of choice what did you find? –  Walter Jan 15 '13 at 20:54
4  
On some tests Boyer-Moore was better on other KMP was better , but I'm not sure i have the "best" implementation of them . As for the language of choice it is in the tags : C++ ( not sure if you saw that since you wrote "language of choice"). P.S. I am also not sure if i tested on the best tests. –  vandamon taigi Jan 15 '13 at 20:57
1  
stackoverflow.com/q/3183582 –  Robert Harvey Jan 15 '13 at 23:21
add comment

2 Answers

up vote 15 down vote accepted

It depends on the kind of search you want to perform. Each of the algorithms performs particularly well for certain types of a search, but you have not stated the context of your searches.

Here are some typical thoughts on search types:

  • Boyer-Moore: works by pre-analyzing the pattern and comparing from right-to-left. If a mismatch occurs, the initial analysis is used to determine how far the pattern can be shifted w.r.t. the text being searched. This works particularly well for long search patterns. In particular, it can be sub-linear, as you do not need to read every single character of your text.

  • Knuth-Morris-Pratt: also pre-analyzes the pattern, but tries to re-use whatever was already matched in the initial part of the pattern to avoid having to rematch that. This can work quite well, if your alphabet is small (f.ex. DNA bases), as you get a higher chance that your search patterns contain reuseable subpatterns.

  • Aho-Corasick: Needs a lot of preprocessing, but does so for a number of patterns. If you know you will be looking for the same search patterns over and over again, then this is much better than the other, because you need to analyse patterns only once, not once per search.

Hence, as usual in CS, there is no definite answer to the overall best. It is rather a matter of choosing the right tool for the job at hand.

Another note on your worst-case reasoning: Do consider the kinds of searches required to create that worst-case and think thoroughly about whether these are really relevant in your case. For example, the O(mn) worst-case complexity of the Boyer-Moore algorithm stems from a search pattern and a text that each use only one character (like finding aaa in aaaaaaaaaaaaaaaaaaaaa) - do you really need to be fast for searches like that?

share|improve this answer
    
I have the whole english alphabet or so to use and I updated the Question , sorry for not starting with this at the begging. –  vandamon taigi Jan 16 '13 at 16:28
    
And yes I do need to be fast even for searches like that –  vandamon taigi Jan 16 '13 at 19:15
add comment

Though I am slightly late to answer this question, but I think Z-Algorithm is much faster than any its counterparts. Its worst-case complexity is O(m+n) and it requires no preprocessing of the pattern/text. It is also very easy to code as compared to the other algorithms.

It works in the following manner.

For example, there is a string S ='abaaba'. We are to find z(i) values for i=0 to len(S)-1. Before going into the explanation, let me put lay down some definitions first.

z(i) = no. of characters of the prefix of S that matches the prefix of s(i).

s(i) = ith suffix of S.

The following are the s(i) values for s = 'abaaba'.

s(0) = 'abaaba' = S
s(1) = 'baaba'
s(2) = 'aaba'
s(3) = 'aba'
s(4) = 'ba'
s(5) = 'a'

The z values are respectively

z(0) = 6 = length(S)
z(1) = 0
z(2) = 1
z(3) = 3
z(4) = 0
z(5) = 1

For detail understanding of the algorithm, refer to the following links.

http://codeforces.com/blog/entry/3107

https://www.youtube.com/watch?v=MFK0WYeVEag

Now it takes O(N) to find all the z values without any pre-processing overhead. One would be wondering now how can you use this logic to match pattern in a given string?

Let's see with an example. Pattern(P) : aba, Text(T) : aacbabcabaad.

Put this in the form P$T. ($ - any character that does not appear in either pattern or text. I'll come to the importance of $ in a little while.)

P$T = aba$aacbabcabaad

We know len(P) = 3.

All z values of P$T are

z(0) = 16 = len(P$T)
z(1) = 0
z(2) = 1
z(3) = 0
z(4) = 1
z(5) = 1
z(6) = 0
z(7) = 0
z(8) = 2
z(9) = 0
z(10) = 0
z(11) = 3
z(12) = 0
z(13) = 1
Z(14) = 1
Z(15) = 0

Now which z(i) = len(P). Ans = 11. So our pattern is present at Ans-len(P)-1 = 7. -1 is for $ character.

Now why $ or any such special character is important. Consider P = 'aaa' and T = 'aaaaaaa'. Without the special character, all z(i) will have incremental values. One can still find the position of pattern in text with the below formulae:

Condition: z(i) >= len(P) and Position: Ans-len(P). But the condition in this case becomes a little tricky and confusing. I personally prefer to use the special character technique.

share|improve this answer
1  
Could you explain it yourself here? Having links to external sites can be used to elaborate, but the core of an answer should be in the answer itself rather than having to follow a link to another site. –  MichaelT Jun 14 at 13:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.