2011-12-21 29 views
20

मैं यथा-स्थान एक के लिए strstr() के बराबर सी में स्ट्रिंग (अर्थात नहीं अशक्त-समाप्त) की गिनती कैसे करते हैं?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

देखें कि नीचे दिया गया कार्य आपके लिए काम करता है या नहीं। मैंने इसे पूरी तरह से परीक्षण नहीं किया है, इसलिए मैं सुझाव दूंगा कि आप ऐसा करते हैं।

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

यह वास्तव में वही है जो मैं वर्तमान में उपयोग कर रहा हूं, लेकिन यह ओ (एमएन) है, जबकि (मुझे लगता है) 'स्ट्रस्ट्र' ओ (एम + एन) है। तो मैं ऐसा कुछ ढूंढ रहा हूं जो मेरे संस्करण की तरह हास्यास्पद रूप से धीमा नहीं है। :-) लेकिन वैसे भी +1, क्योंकि विचार काम करता है। – Mehrdad

+0

@ मेहरदाद: इस कार्यान्वयन पर एक झांक लेने के लिए भी लायक हो सकता है: http://src.gnu-darwin.org/src/lib/libc/string/strnstr.c.html –

+0

वाह, मुझे लगता है कि मैं गलत था तो ... तो 'स्ट्रस्ट्र' आमतौर पर एक ओ (एमएन) ऑपरेशन के रूप में परिभाषित किया जाता है ?? इसे इंगित करने के लिए धन्यवाद ... तो मैं शायद इसे थोड़ा सा स्वीकार करूंगा, क्योंकि यह प्रश्न के लिए सही विकल्प है। – 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

आगे बढ़ना चाहिए और इसे बॉयर-मूर बनाया जाना चाहिए;) –