사용자 도구

사이트 도구


ps:문자열_매칭

문자열 매칭

  • 주어진 문자열 S 안에 어떤 패턴문자열 P가 존재하는지, 몇개나 존재하는지, S의 몇번째 인덱스에 있는지 등등을 처리하는 매우 실용적인 문제
  • 문자열 매칭을 위한 알고리즘들은 여러가지가 있다. len(S) = N, len(P) = M이라고 하자
    • 나이브 매칭 O(NM)
      • 노커멘트
      • 해시 펑션을 이용하기 때문에, 해시 충돌로 오답이 나올 확률이 존재하기는 한다 (거의 없다)
      • PS에서 사용되는 표준적인(?) 문자열 매칭 알고리즘.
      • Z 알고리즘으로도 선형시간에 문자열 매칭이 가능하긴 하다
      • 평균적으로는 KMP보다 빨라서 실용적으로는 더 선호되지만, 최악을 막는게 중요한 PS계열에서는 사용 불가
      • KMP와 보이어무어를 잘 조합해서, 최악 경우에도 선형시간을 유지하도록 만들었다고 한다.
  • 파이썬에 내장된 str.__contains__() 또는 str.find() 함수는 3.10 이후부터 Two-way string-matching algorithm 으로 구현되었다고 한다 stackoverflow 게시물
  • 따라서 기본적으로는 다 필요없고.. 그냥 내장 함수를 쓰는것이 가장 빠르고 편리하다.
    • 그냥 빠른 정도가 아니라, '압도적으로' 빠르다.
  • 하지만, str.find()는, '첫번째' 매칭 위치만 알려준다는 제한이 있다. 오버래핑되는 '모든' 매칭의 위치를 찾기 위해서 str.find()를 반복해서 쓰는것은 O(N^2)이 되므로, 이 경우에는 알고리즘을 구현해야 한다.
  • 구현할때는, 라빈-카프 알고리즘 (Rabin-Karp Algorithm), KMP 알고리즘, Z 알고리즘이 다 가능하지만, 일반적으로 KMP 알고리즘이 그냥 제일 무난하고 빠르니까 이거를 쓰자.
  • 세줄 요약
    • 존재여부 또는 첫번째 매칭위치만 찾으면 된다면 그냥 내장 str 함수를 쓴다
    • 리스트와 같이 문자열이 아닌 시퀀스에서 매칭을 해야 할 경우에도 가능하면 문자열로 변환해서 내장함수를 쓰자.
    • 내장함수로 해결이 안될경우에는 KMP 알고리즘(teflib.string.find) 을 쓴다.
      • 대표적으로, '모든' 매칭위치를 찾을때이다.

토론

댓글을 입력하세요:
M A J J M
 
ps/문자열_매칭.txt · 마지막으로 수정됨: 2022/12/10 03:30 저자 teferi