2011-12-21 3 views
20

어떻게이 에 대한 strstr()현재 위치에서 동등한 C에서 (즉 하지 null로 끝나는) 문자열을 계산해야합니까?않는 strstr()

+3

고유 한 버전을 작성해야합니다. –

+0

어떤 문자열이 널 종료되지 않습니까? 검색되는 문자열 또는 하위 문자열? –

+0

@TimCooper : 검색중인 (건초 더미). – Mehrdad

답변

5

- 기본적으로, 당신은 필요가 없습니다, 이러한 경우는 자연적으로 발생하지 않습니다 - 나는 여기에 수정 한 어떤 주위에 내가 거짓말을했던 KMP 구현입니다 건초 더미의 길이를 가져라. 래퍼도. 반복 검색을 원하면 직접 작성하고 borders 배열을 다시 사용하십시오.

버그 방지에 대한 보장은 없지만 여전히 작동하는 것으로 보입니다.

int *kmp_borders(char *needle, size_t nlen){ 
    if (!needle) return NULL; 
    int i, j, *borders = malloc((nlen+1)*sizeof(*borders)); 
    if (!borders) return NULL; 
    i = 0; 
    j = -1; 
    borders[i] = j; 
    while((size_t)i < nlen){ 
     while(j >= 0 && needle[i] != needle[j]){ 
      j = borders[j]; 
     } 
     ++i; 
     ++j; 
     borders[i] = j; 
    } 
    return borders; 
} 

char *kmp_search(char *haystack, size_t haylen, char *needle, size_t nlen, int *borders){ 
    size_t max_index = haylen-nlen, i = 0, j = 0; 
    while(i <= max_index){ 
     while(j < nlen && *haystack && needle[j] == *haystack){ 
      ++j; 
      ++haystack; 
     } 
     if (j == nlen){ 
      return haystack-nlen; 
     } 
     if (!(*haystack)){ 
      return NULL; 
     } 
     if (j == 0){ 
      ++haystack; 
      ++i; 
     } else { 
      do{ 
       i += j - (size_t)borders[j]; 
       j = borders[j]; 
      }while(j > 0 && needle[j] != *haystack); 
     } 
    } 
    return NULL; 
} 

char *sstrnstr(char *haystack, char *needle, size_t haylen){ 
    if (!haystack || !needle){ 
     return NULL; 
    } 
    size_t nlen = strlen(needle); 
    if (haylen < nlen){ 
     return NULL; 
    } 
    int *borders = kmp_borders(needle, nlen); 
    if (!borders){ 
     return NULL; 
    } 
    char *match = kmp_search(haystack, haylen, needle, nlen, borders); 
    free(borders); 
    return match; 
} 
+0

: 오 이런, 분명히 이것을 시도 할 것입니다! 감사! :) – Mehrdad

5

다음 기능이 효과가 있는지 확인하십시오. 나는 그것을 철저히 시험하지 않았으므로 그렇게하도록 권할 것이다. 당신은 O (m의 * n)도 동작을 두려워하는 경우

char *sstrstr(char *haystack, char *needle, size_t length) 
{ 
    size_t needle_length = strlen(needle); 
    size_t i; 

    for (i = 0; i < length; i++) 
    { 
     if (i + needle_length > length) 
     { 
      return NULL; 
     } 

     if (strncmp(&haystack[i], needle, needle_length) == 0) 
     { 
      return &haystack[i]; 
     } 
    } 
    return NULL; 
} 
+0

그것은 실제로 현재 사용하고있는 것과 비슷하지만, O (mn) 인 반면, (strstr)은 O (m + n)라고 가정합니다. 그래서 나는 내 버전처럼 엄청나게 느리지 않은 무언가를 찾고있다. :-)하지만 어쨌든 +1은 생각이 작동하기 때문에. – Mehrdad

+0

@Mehrdad : http://src.gnu-darwin.org/src/lib/libc/string/strnstr.c.html –

+0

와우, 내가 잘못 생각한 것 같습니다. 그러면 ... strstr은 일반적으로 O (mn) 연산으로 정의됩니다. ?? 그 점을 지적 해 주셔서 고마워요. 그러면 그 질문에 대한 정확한 대체물이기 때문에 아마도 조금 받아 들일 것입니다. – Mehrdad

2

방금이 문제가 발생했습니다. 구현 방법을 공유하고 싶습니다. 그것은 아주 빠르다고 생각합니다. 저는 서브 콜이 없습니다.

바늘이있는 건초 더미에서 색인을 찾지 못하면 -1을 반환합니다.

/* binary search in memory */ 
int memsearch(const char *hay, int haysize, const char *needle, int needlesize) { 
    int haypos, needlepos; 
    haysize -= needlesize; 
    for (haypos = 0; haypos <= haysize; haypos++) { 
     for (needlepos = 0; needlepos < needlesize; needlepos++) { 
      if (hay[haypos + needlepos] != needle[needlepos]) { 
       // Next character in haystack. 
       break; 
      } 
     } 
     if (needlepos == needlesize) { 
      return haypos; 
     } 
    } 
    return -1; 
} 
+1

앞으로 나아가 야하고 Boyer-Moore가 되어라.) –