首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言實作:不依賴庫函數的子字串刪除算法

     編輯:關於C語言

在嵌入式開發或面試手寫代碼時,經常需要在不使用標準庫 string.h 的情況下實現字串操作。本文提供一個純 C 實現的 del_substr 函數,用於從原字串中刪除首次出現的指定子字串,並附帶完整註解與邏輯解析。

核心思路:雙指針掃描 + 記憶體前移覆蓋

  1. 定位子字串:在主字串中尋找子字串首次出現的起始位址。
  2. 計算長度:自行實現 my_strlen 獲取子字串長度。
  3. 記憶體前移:將子字串後方的字元向前覆蓋,填補空缺,最後補上 \0。

完整代碼實現

#include <stdio.h>

int del_substr(char *str, char const *substr);
int my_strlen(char const *str);

int main(void) {
    char str[] = "abcdefgh";
    char *substr1 = "efg";
    char *substr2 = "fgr";

    printf("%d\t%s\n", del_substr(str, substr1), str); // 找到並刪除,輸出 1 和 "abcdh"
    printf("%d\t%s\n", del_substr(str, substr2), str); // 未找到,輸出 0 和 "abcdh"
    return 0;
}

/**
 * 刪除 str 中首次出現的 substr
 * 成功返回 1,失敗返回 0
 */
int del_substr(char *str, char const *substr) {
    int i = 0;
    char *temp_str = str;
    char const *temp_substr = substr;
    int sub_len = my_strlen(substr);

    // 1. 尋找子字串起始位置
    while (1) {
        if (*temp_str == *temp_substr) {
            temp_substr++;
            if (*temp_substr == '\0') break; // 完整匹配
        } else {
            temp_substr = substr; // 重置子字串指針
        }
        if (*temp_str == '\0') return 0; // 遍歷完主字串未找到
        temp_str++;
    }

    // 2. 計算刪除起始位址
    char *preDel = temp_str - (sub_len - 1);

    // 3. 記憶體前移覆蓋
    while (*(preDel + (i + sub_len)) != '\0') {
        *(preDel + i) = *(preDel + (i + sub_len));
        i++;
    }
    *(preDel + i) = '\0'; // 結尾補零
    return 1;
}

// 簡易 strlen 實現
int my_strlen(char const *str) {
    int len = 0;
    while (*str++ != '\0') len++;
    return len;
}

關鍵邏輯詳細解析

1. 子字串匹配演算法

使用兩個指針 temp_str(遍歷主字串)和 temp_substr(遍歷子字串)。

  • 字元相等時,temp_substr 後移繼續比對。
  • 字元不等時,temp_substr 重置指向子字串開頭,temp_str 繼續後移。
  • 若 temp_substr 走到 \0,表示完整匹配,跳出循環;此時 temp_str 指向匹配區間的最後一個字元。

2. 刪除起始位址計算

preDel = temp_str - (sub_len - 1) 將指針回退到匹配區間的第一個字元,這就是要被覆蓋的起始位置。

3. 就地覆蓋(In-place Shift)

將 preDel + sub_len 之後的所有字元(含結尾 \0)依次向前搬移 sub_len 個位置,時間複雜度 O(n),空間複雜度 O(1)。

測試輸出說明

1       abcdh   // "efg" 被刪除
0       abcdh   // "fgr" 不存在,字串不變

避坑指南與改進方向

  • 邊界條件:子字串為空、主字串為空、子字串長於主字串,建議在函數開頭加上防禦性判斷。
  • 多次刪除:若需刪除所有出現的子字串,可在外層包裹循環,直到返回 0 為止。
  • 安全性:實際專案中優先使用 strstr + memmove,標準庫經過優化且經過充分測試。

這個練習不僅考驗指針操作功力,更能幫助理解字串在記憶體中的連續佈局與就地修改技巧,是 C 語言進階的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved