strstr () для строки, которая НЕ заканчивается на нуль - PullRequest
25 голосов
/ 21 декабря 2011

Как мне сделать на месте эквивалент strstr() для подсчитанной строки (т. Е. не с нулевым символом в конце) в C?

Ответы [ 4 ]

8 голосов
/ 21 декабря 2011

Посмотрите, работает ли функция ниже для вас. Я не проверил это полностью, поэтому я бы посоветовал вам сделать это.

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;
}
7 голосов
/ 21 декабря 2011

Если вы боитесь поведения O (m * n) - в принципе, вам это не нужно, такие случаи не происходят естественным образом - вот моя реализация 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;
}
4 голосов
/ 05 мая 2015

Я только что столкнулся с этим, и я хотел бы поделиться своей реализацией.Он думает, что это довольно быстро, и у меня нет никаких дополнительных вызовов.

Возвращает индекс в стоге сена, где была найдена игла, или -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;
}
0 голосов
/ 02 октября 2018

Я использовал этот метод

int memsearch(char* dataset, int datasetLength, char* target, int targetLen){
    for(int i = 0; i < datasetLength; i++){
            if(dataset[i] == target[0]){
                    int found = 1;
                    for(int j = 0; j < targetLen; j++){
                            int k = i + j;
                            if(k >= datasetLength || target[j] != dataset[k]){
                                    found = 0;
                                    break;
                            }
                    }
                    if(found) return i;
            }
    }
    return -1;
}
...