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

Java 統計字符串/文件中指定字符出現次數的高效實現

     編輯:Java 相關知識

前言

統計字符/子串出現次數是常見文本處理需求。本文提供文件級與內存級兩種實現,並分析時間/空間複雜度。

方案一:文件流逐行讀取 + indexOf 循環(適合大文件)

public static int countInFile(String filePath, String target) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) sb.append(line);
        return countInString(sb.toString(), target);
    }
}

private static int countInString(String text, String target) {
    int count = 0, idx = 0;
    while ((idx = text.indexOf(target, idx)) != -1) {
        count++;
        idx += target.length();  // 非重疊匹配;若需重疊用 idx++
    }
    return count;
}

特點:流式讀取,內存佔用 ≈ 文件大小(可改用 MappedByteBuffer 零拷貝優化)。

方案二:純內存字符串統計(適合中小文本)

// Apache Commons Lang 一行式
int count = StringUtils.countMatches(text, target);

// 或手寫(同上 indexOf 邏輯)
public static int countMatches(String text, String target) {
    if (text == null || target == null || target.isEmpty()) return 0;
    int count = 0, idx = 0;
    while ((idx = text.indexOf(target, idx)) != -1) {
        count++;
        idx += target.length();
    }
    return count;
}

方案三:正則表達式(功能最強,性能稍弱)

public static int countRegex(String text, String regex) {
    Matcher m = Pattern.compile(regex).matcher(text);
    int count = 0;
    while (m.find()) count++;
    return count;
}
// 用法:countRegex("ababa", "aba") → 1(非重疊);重疊需用 lookahead "(?=aba)"

性能對比(百萬字符級測試參考)

方法耗時內存適用場景
indexOf 循環最快O(1) 額外固定子串、高頻調用
StringUtils.countMatches快O(1)通用工具類
正則 Matcher.find較慢O(1)模式匹配、重疊統計

進階:重疊匹配統計

// 文本 "aaa" 統計 "aa" 出現 2 次(位置 0、1)
public static int countOverlapping(String text, String target) {
    int count = 0, idx = 0;
    while ((idx = text.indexOf(target, idx)) != -1) {
        count++;
        idx++;  // 只移動一位,允許重疊
    }
    return count;
}
// 正則寫法:Pattern.compile("(?=" + Pattern.quote(target) + ")")

總結建議

  • 固定子串、高性能 → indexOf 循環 / StringUtils.countMatches。
  • 大文件 → 流式讀取 + indexOf,避免一次性載入內存。
  • 複雜模式/重疊 → 正則 lookahead。
  • 引入 commons-lang3 依賴可直接用 StringUtils,生產級項目推薦。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved