在2G大小的文件中,找出高頻top100的單詞

  1. 將 2GB 的大文件分割為 2048 個大小為 512KB 的小文件,采用流式讀取方式處理,避免一次性加載整個文件導致內存溢出。

  2. 初始化一個長度為 2048 的哈希表數組,用于分別統計各個小文件中單詞的出現頻率。

  3. 利用多線程并行處理機制遍歷所有 2048 個小文件,對每個文件中的單詞執行哈希取模運算(int hash = Math.abs(word.hashCode() % hashTableSize)),并通過hashTables[hash].merge(word, 1, Integer::sum)的方式將單詞頻率累加到對應的哈希表中。

  4. 遍歷這 2048 個哈希表,對每個哈希表中的單詞按頻率排序,將頻率排名前 100 的單詞存入一個小頂堆。

  5. 經過上述處理后,小頂堆中最終保留的 100 個單詞即為整個文件中出現頻率最高的前 100 個單詞。

package com.example.bigfiletop100;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;public class Top100Words {private static final int HASH_TABLE_SIZE = 2048;private static final int TOP_WORDS_COUNT = 100;public static void main(String[] args) throws IOException, InterruptedException {String largeFilePath = "C:\\Users\\亞洲\\IdeaProjects\\springboot-easyexcel-mybatisplus\\src\\main\\java\\com\\example\\bigfiletop100\\input.txt"; // 替換為大文件的路徑String tempDirPath = "C:\\Users\\亞洲\\IdeaProjects\\springboot-easyexcel-mybatisplus\\src\\main\\java\\com\\example\\bigfiletop100\\temp_files"; // 替換為臨時目錄的路徑Path tempDir = Paths.get(tempDirPath);if (!Files.exists(tempDir)) {Files.createDirectories(tempDir);}// 1. 分割大文件為512KB的小文件(改進版)splitFile(largeFilePath, tempDir.toString(), 512 * 1024);// 2. 初始化哈希表數組ConcurrentHashMap<Integer, Map<String, Integer>> hashTables = new ConcurrentHashMap<>();for (int i = 0; i < HASH_TABLE_SIZE; i++) {hashTables.put(i, new ConcurrentHashMap<>());}// 3. 并行遍歷小文件,統計單詞頻率File[] smallFiles = new File(tempDir.toString()).listFiles((dir, name) -> name.endsWith(".txt"));if (smallFiles == null || smallFiles.length == 0) {System.err.println("No small files found.");return;}ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());CountDownLatch latch = new CountDownLatch(smallFiles.length);for (File smallFile : smallFiles) {executor.submit(() -> {try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(smallFile), StandardCharsets.UTF_8))) {String line;while ((line = reader.readLine()) != null) {String[] words = line.trim().split("\\s+");for (String word : words) {if (word.isEmpty()) continue;int hash = Math.abs(word.hashCode() % HASH_TABLE_SIZE);hashTables.get(hash).merge(word, 1, Integer::sum);}}} catch (IOException e) {System.err.println("Error reading file: " + smallFile.getName());e.printStackTrace();} finally {latch.countDown();}});}executor.shutdown();latch.await(); // 等待所有任務完成// 4. 合并哈希表,并把頻率前100的單詞存入小頂堆PriorityQueue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(TOP_WORDS_COUNT,(o1, o2) -> o1.getValue().compareTo(o2.getValue()));hashTables.values().stream().filter(Objects::nonNull).flatMap(map -> map.entrySet().stream()).forEach(entry -> {if (minHeap.size() < TOP_WORDS_COUNT) {minHeap.offer(entry);} else if (entry.getValue() > minHeap.peek().getValue()) {minHeap.poll();minHeap.offer(entry);}});// 5. 輸出結果System.out.println("Top " + TOP_WORDS_COUNT + " words:");List<Map.Entry<String, Integer>> topWords = new ArrayList<>(minHeap);topWords.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue())); // 按降序排列topWords.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));// 清理臨時文件和目錄Arrays.stream(smallFiles).forEach(File::delete);Files.deleteIfExists(tempDir);}private static void splitFile(String largeFilePath, String tempDir, int size) throws IOException {try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(largeFilePath))) {byte[] buffer = new byte[size];int bytesRead;int fileCount = 0;while ((bytesRead = bis.read(buffer)) != -1) {File smallFile = new File(tempDir, "part-" + fileCount++ + ".txt");// 避免截斷單詞int actualBytesRead = bytesRead;if (bytesRead <= size && buffer[bytesRead - 1] != '\n') {// 查找最后一個空格或換行符作為分割點for (int i = bytesRead - 1; i >= 0; i--) {if (buffer[i] == ' ' || buffer[i] == '\n') {actualBytesRead = i + 1;bis.reset();bis.skip(actualBytesRead);break;}}}try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(smallFile))) {bos.write(buffer, 0, actualBytesRead);}}}}
}

關鍵說明

  1. 文件分割優化
    分割時避免截斷單詞(通過查找最后一個非字母位置),確保每個單詞完整屬于一個小文件,避免統計誤差。

  2. 內存控制
    單個小文件 512KB,2G 文件約 4096 個小文件(而非 2048,更保守),每個小文件單獨處理,避免 OOM。

  3. 多線程效率
    使用線程池(大小為 CPU 核心數)并行處理小文件,提升統計速度,哈希表數組避免線程競爭(每個哈希槽獨立)。

  4. 小頂堆篩選
    堆大小固定為 100,每次插入復雜度 O (log 100),整體效率遠高于全量排序(O (n log n))。

  5. 單詞處理
    統一轉為小寫(忽略大小寫差異),用正則提取純字母單詞(可根據需求調整匹配規則,如保留數字)。

此方案適用于大文件場景,通過分治思想將問題拆解為可并行處理的子任務,再通過堆排序高效篩選結果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916526.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916526.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916526.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于LNMP分布式個人云存儲

1.準備工作a.關閉兩臺虛擬機的安全軟件客戶端&#xff1a;[rootmaster ~]# systemctl stop firewalld [rootmaster ~]# systemctl disable firewalld [rootmaster ~]# systemctl status firewalld ○ firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (…

指針運算全攻略:加減、比較與排序

常見的指針指針運算說明1.指針與整數的加減運算對指針可以進行加法運算&#xff0c;即p n或者p - n。其結果依舊是一個是一個指針&#xff0c;新的指針是在原來的地址值基礎上加上/減去n *(sizeof(指針指向的數據類型)&#xff09;個字節。示例&#xff1a;#include<stdio.…

物聯網安裝調試-物聯網網關

物聯網網關作為連接終端設備與云平臺的核心樞紐,其分類與選型需結合功能定位、硬件性能、連接方式及應用場景等多維度考量。以下從分類體系和產品推薦兩方面系統梳理,助您高效決策: ?? 一、物聯網網關分類體系 1. 按功能定位劃分 類型 核心能力 典型場景 代表產品 邊緣計…

Jenkins教程(自動化部署)

Jenkins教程(自動化部署) 1. Jenkins是什么&#xff1f; Jenkins是一個開源的、提供友好操作界面的持續集成(CI)工具&#xff0c;廣泛用于項目開發&#xff0c;具有自動化構建、測試和部署等功能。Jenkins用Java語言編寫&#xff0c;可在Tomcat等流行的servlet容器中運行&…

linux 驅動驗證是否成功 之 查看moudle信息

這些是 Linux 內核模塊&#xff08;.ko&#xff09;中的元信息&#xff08;metadata&#xff09;&#xff0c;可以通過如下方式查看&#xff1a;? 1. 使用 modinfo 命令查看已加載或已編譯模塊信息 示例&#xff1a; modinfo aw2013.ko輸出內容大概如下&#xff1a; filename:…

瀏覽器關閉之前請求接口到后端

2025.07.24今天我學習了如何在瀏覽器關閉之前請求一個接口返回到后端。可以用performance.navigation判斷是瀏覽器關閉&#xff0c;還是瀏覽器刷新&#xff0c;因為我這邊只需要瀏覽器關閉的時候才去觸發1. 利用performance API&#xff08;刷新檢測&#xff09; 刷新頁面時&am…

MySQL批量數據處理與事務管理

MySQL是一種廣泛應用的關系型數據庫管理系統&#xff0c;尤其在數據分析和業務邏輯處理方面具有重要地位。在數據量龐大的業務場景中&#xff0c;批量數據處理和事務管理是提高效率和保障數據一致性的重要手段。掌握高效的批量數據操作方法與事務管理技巧&#xff0c;不僅能夠提…

iOS網絡之異步加載

為什么你的圖片要異步加載&#xff1f;在仿寫天氣預報時&#xff0c;我們常常需要從網絡加載天氣圖標&#xff0c;例如顯示某個小時的天氣狀態圖標。這看似簡單的事情&#xff0c;如果處理不當&#xff0c;卻很容易造成界面卡頓&#xff0c;甚至影響整個 App 的用戶體驗。錯誤做…

C#值類型屬性的典型問題

問題復現&#xff1a;值類型屬性的副本問題以下代碼展示了值類型屬性的典型問題&#xff1a;struct Point {public int X;public int Y; }class MyClass {public Point Position {get; set;} }// 使用屬性修改結構體&#xff08;無效&#xff01;&#xff09; var obj new MyC…

機器學習基礎-k 近鄰算法(從辨別水果開始)

一、生活中的 "分類難題" 與 k 近鄰的靈感 你有沒有這樣的經歷&#xff1a;在超市看到一種從沒見過的水果&#xff0c;表皮黃黃的&#xff0c;拳頭大小&#xff0c;形狀圓滾滾。正當你猶豫要不要買時&#xff0c;突然想起外婆家的橘子好像就是這個樣子 —— 黃色、圓…

【WPF】NumericUpDown的用法

在 WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;NumericUpDown 控件并不是內置的標準控件之一&#xff0c;但它是一個非常常用的控件&#xff0c;用于讓用戶輸入一個數值&#xff08;整數或浮點數&#xff09;&#xff0c;并提供上下箭頭來遞增或…

Kotlin位運算

Kotlin 提供了幾種用于操作整數各個位&#xff08;bit&#xff09; 的運算符。這些操作是由處理器直接支持的&#xff0c;速度快且操作簡單。在底層編程中非常重要&#xff0c;比如設備驅動、低級圖形處理、網絡通信、加密和壓縮等。 盡管計算機通常都有高效的硬件指令來執行算…

墨者:通過手工解決SQL手工注入漏洞測試(MongoDB數據庫)

一、SQL手工注入漏洞測試(MongoDB數據庫) 本文以墨者學院靶場為例&#xff0c;演示MongoDB數據庫的手工SQL注入全過程。靶場以自己的地址為準&#xff1a;http://124.70.71.251:42286/new_list.php?id1 二、注入原理說明 MongoDB作為NoSQL數據庫&#xff0c;其注入方式與傳…

Kafka——CommitFailedException異常處理深度解析

引言在分布式消息系統Kafka的生態中&#xff0c;消費者組&#xff08;Consumer Group&#xff09;機制是實現高吞吐量和負載均衡的核心設計。然而&#xff0c;消費過程中位移提交&#xff08;Offset Commit&#xff09;的穩定性始終是開發者面臨的最大挑戰之一。當消費者嘗試提…

kafka的部署和jmeter連接kafka

zookeeper的安裝 kafka依賴Zookeeper所以要先安裝Zookeeper kafka的安裝文章引用來源:Kafka下載和使用&#xff08;linux版&#xff09;-CSDN博客 通過wget命令安裝 # 安裝wget https://downloads.apache.org/zookeeper/stable/apache-zookeeper-3.7.1-bin.tar.gz# 解壓tar…

Android UI 組件系列(八):ListView 基礎用法與適配器詳解

博客專欄&#xff1a;Android初級入門UI組件與布局 源碼&#xff1a;通過網盤分享的文件&#xff1a;Android入門布局及UI相關案例 鏈接: https://pan.baidu.com/s/1EOuDUKJndMISolieFSvXXg?pwd4k9n 提取碼: 4k9n 一、引言 在上一篇文章《Android UI 組件系列&#xff08;…

Android學習專題目錄(持續更新)

1.Android 調試 1.1&#xff1a;Logcat日志分析 2.Android編譯 2.1&#xff1a;android編譯過程中的mk文件和bp文件的掃描機制 2.2&#xff1a;Android 構建系統中常見的 .mk 文件及其作用 2.3&#xff1a;Android構建系統中的mk文件語法函數 2.4&#xff1a;安卓中定…

c#Lambda 表達式與事件核心知識點整理

一、Lambda 表達式1. 概念 Lambda 表達式是一種匿名函數&#xff08;無名稱的函數&#xff09;&#xff0c;簡化了委托和匿名方法的寫法&#xff0c;格式為&#xff1a; (參數列表) > 表達式或語句塊 它可以作為參數傳遞&#xff0c;或賦值給委托類型變量。2. 基本語法與簡寫…

Springboot+Layui英語單詞學習系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBootLayUI框架持久層框架MyBaits成功系統案例&#xff1a;參考代碼數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續輸…

主要分布于內側內嗅皮層的層Ⅲ的邊界向量細胞(BVCs)對NLP中的深層語義分析的積極影響和啟示

邊界向量細胞&#xff08;Boundary Vector Cells, BVCs&#xff09;主要分布于內側內嗅皮層&#xff08;MEC&#xff09;層Ⅲ&#xff0c;通過編碼環境邊界&#xff08;如墻壁、障礙物&#xff09;的距離和方向信息&#xff0c;為空間導航提供幾何參考框架。這一神經機制對自然…