記錄一下自己的最佳化字串匹配演算法

Churk發表於2024-11-02

我願稱之KeBF演算法

Ke的BF(Brute Force,暴力檢索)法

關於其他 字串匹配演算法

示例原始碼

#include <stdio.h>
#include <string.h>

int main()
{
    // 讀入兩個字串
    char ms[100], ps[100];
    fgets(ms, sizeof(ms), stdin);
    fgets(ps, sizeof(ps), stdin);

    // 去掉換行符
    ms[strcspn(ms, "\n")] = '\0';
    ps[strcspn(ps, "\n")] = '\0';

    int j = 0, index[100];
    int msL = strlen(ms);
    int psL = strlen(ps);
    // 演算法實現
    for (int i = 0; i <= msL - psL; )
    {
        if ((msL - i) < psL)
            break;
        int t = 0;
        while (t < psL && ms[i + t] == ps[t])
            t++;
        if (t == psL)
        {
            index[j] = i;
            j++;
            i += t;
        }
        else
            i += (t > 0) ? t : 1;
    }
    // 輸出結果
    if (j > 0)
        for (int i = 0; i < j; i++)
            printf("%d ", index[i]);
    else
        printf("None");
    printf("\n");

    return 0;
}

與FittenCode的鬥志鬥勇

大勝利!

所以——

誰能拒絕一個寫法比KMP簡單,時間複雜度摸摸KMP(O(n) & O(m+n)),空間複雜度大概持平KMP的可可愛愛的KeBF呢😘

附 KMP 示例原始碼

別問,問就是fittenCode寫的()

#include <stdio.h>
#include <string.h>

// 函式宣告
void computeNext(const char *pattern, int *next);
void kmpSearch(const char *text, const char *pattern);

int main() {
    char text[100];
    char pattern[100];

    // 輸入主串和模式串
    printf("請輸入主串: ");
    fgets(text, sizeof(text), stdin);
    printf("請輸入模式串: ");
    fgets(pattern, sizeof(pattern), stdin);

    // 去掉換行符
    text[strcspn(text, "\n")] = '\0';
    pattern[strcspn(pattern, "\n")] = '\0';

    // 呼叫 KMP 查詢函式
    kmpSearch(text, pattern);

    return 0;
}

// 計算模式串的 next 陣列
void computeNext(const char *pattern, int *next) {
    int m = strlen(pattern);
    next[0] = 0; // next[0] 是始終為 0

    int j = 0; // j 代表字首長度
    for (int i = 1; i < m; i++) {
        while (j > 0 && pattern[i] != pattern[j]) {
            j = next[j - 1]; // 回溯到前一個最佳匹配
        }
        if (pattern[i] == pattern[j]) {
            j++; // 匹配繼續
        }
        next[i] = j; // 記錄當前字元匹配的字首長度
    }
}

// KMP 字串查詢
void kmpSearch(const char *text, const char *pattern) {
    int n = strlen(text);
    int m = strlen(pattern);
    int next[m];

    // 計算模式串的 next 陣列
    computeNext(pattern, next);

    int j = 0; // j 代表當前匹配的模式串中的位置
    for (int i = 0; i < n; i++) {
        while (j > 0 && text[i] != pattern[j]) {
            j = next[j - 1]; // 發生不匹配,回溯到前一個最佳匹配
        }
        if (text[i] == pattern[j]) {
            j++; // 字元匹配,移動到模式串的下一個位置
        }
        if (j == m) {
            printf("找到匹配,起始位置: %d\n", i - m + 1); // 找到匹配,輸出起始位置
            j = next[j - 1]; // 準備進行下一個匹配
        }
    }
}

相關文章