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

Java 統計字符串中子串出現次數:三種高效實現方案

     編輯:Java 相關知識

問題描述

給定字符串 str 與子串 sub,統計 sub 在 str 中**不重疊**出現的次數。例如 "java java java" 包含 "java" 3 次。

方案一:indexOf 循環遞歸 (通用、易懂)

public static int countSubstring(String str, String sub) {
    int count = 0;
    int idx = 0;
    while ((idx = str.indexOf(sub, idx)) != -1) {
        count++;
        idx += sub.length(); // 移動到下一個可能位置,避免重疊
    }
    return count;
}

優點:邏輯清晰,支援任意子串。
缺點:創建多個子字符串對象 (若用 substring),可優化為僅移動索引。

方案二:split 分割法 (極簡、僅限非正則元字符)

public static int countBySplit(String str, String sub) {
    if (str == null || sub == null || sub.isEmpty()) return 0;
    // split 會將正則元字符轉義,若 sub 含特殊字符需 Pattern.quote
    String[] parts = str.split(Pattern.quote(sub));
    return parts.length - 1;
}

注意:sub 若包含正則元字符 (如 .*+?[]()) 必須用 Pattern.quote 轉義,否則會按正則匹配導致錯誤。

方案三:Matcher 正則查找 (功能最強、支援重疊/邊界控制)

public static int countByMatcher(String str, String sub) {
    if (str == null || sub == null || sub.isEmpty()) return 0;
    Pattern pattern = Pattern.compile(Pattern.quote(sub));
    Matcher matcher = pattern.matcher(str);
    int count = 0;
    while (matcher.find()) count++;
    return count;
}

進階**:若需**重疊匹配** (如 "aaa" 中 "aa" 出現 2 次),可用 Pattern.compile("(?=" + Pattern.quote(sub) + ")") 零寬斷言。

效能與選型建議

方案時間複雜度適用場景備註
indexOf 循環O(N*M)通用、無正則依賴最推薦日常使用
splitO(N)一次性統計、子串固定需注意正則轉義
MatcherO(N)複雜匹配、重疊、邊界功能最全、物件開銷稍大

完整測試類

public class SubstringCounter {
    public static void main(String[] args) {
        String text = "sdSS**&HGJhadHCASch& ^^";
        String target = "java"; // 示例中原文統計 "java",實際文本不含,結果為 0
        
        System.out.println("indexOf: " + countSubstring(text, target));
        System.out.println("split:   " + countBySplit(text, target));
        System.out.println("Matcher: " + countByMatcher(text, target));
    }
    // 三個靜態方法放這裡...
}

面試加分點:主動說明 split 的正則陷阱與 Matcher 的零寬斷言重疊匹配技巧,展現對 API 細節的深度理解。

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