在兩個大文件中找出相同的記錄,用 golang 如何寫?
在 Go 語言中找出兩個大文件中相同的記錄,可以採用以下策略:
思路
-
讀文件:按行逐行讀取兩個文件中的記錄,假設每個文件的每一行代表一條記錄。
-
使用哈希集合(Set):因爲哈希集合能夠快速判斷某個記錄是否存在,所以我們可以將第一個文件中的記錄放入集合中,之後讀取第二個文件時逐行判斷該記錄是否也存在於集合中。如果存在則是相同的記錄。
-
性能優化:
-
如果文件非常大,避免一次性全部加載到內存中,而是逐行處理。
-
如果文件非常大且存在重複數據,可以先對文件中的數據去重。
代碼實現
package main
import (
"bufio"
"fmt"
"os"
"log"
)
// 從文件中讀取數據並返回一個map,記錄每一行的出現次數
func readFileToSet(filename string) (map[string]bool, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
recordSet := make(map[string]bool)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
recordSet[line] = true
}
if err := scanner.Err(); err != nil {
return nil, err
}
return recordSet, nil
}
// 找出兩個文件中相同的記錄
func findCommonRecords(file1, file2 string) ([]string, error) {
// 讀取第一個文件到Set
recordSet, err := readFileToSet(file1)
if err != nil {
return nil, err
}
// 打開第二個文件並逐行讀取
file, err := os.Open(file2)
if err != nil {
return nil, err
}
defer file.Close()
var commonRecords []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if recordSet[line] {
commonRecords = append(commonRecords, line)
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return commonRecords, nil
}
func main() {
file1 := "file1.txt"
file2 := "file2.txt"
commonRecords, err := findCommonRecords(file1, file2)
if err != nil {
log.Fatalf("Error finding common records: %v", err)
}
fmt.Println("Common Records:")
for _, record := range commonRecords {
fmt.Println(record)
}
}
代碼分析
readFileToSet:
- 用於將一個文件中的記錄(逐行)讀取到一個
map[string]bool的哈希集合中,確保文件中的每一行記錄唯一存在於集合中。
findCommonRecords:
-
首先調用
readFileToSet讀取第一個文件,將其存儲在哈希集合recordSet中。 -
然後打開第二個文件,逐行讀取並判斷該記錄是否存在於第一個文件的集合中,如果存在,則將該記錄加入到
commonRecords切片中。
main:
- 設置兩個文件的路徑,調用
findCommonRecords函數來查找相同的記錄,並輸出結果。
性能優化
- 減少內存佔用:
-
只需將第一個文件的所有記錄加載到內存中,第二個文件逐行讀取並判斷。
-
如果文件過大,可採用外部排序的方式,或將文件分塊處理。
- 併發處理:
- 可以考慮對兩個文件的讀取操作進行併發處理,或在有多個處理器的情況下對文件的不同部分進行並行處理。
使用案例
假設 file1.txt 和 file2.txt 的內容如下:
file1.txt:
apple
banana
cherry
grape
orange
file2.txt:
pear
banana
grape
watermelon
apple
運行程序後,輸出結果爲:
Common Records:
apple
banana
grape
結論
這種解決方案使用哈希集合快速查找,可以高效處理兩個大文件的記錄比較,且通過 bufio.Scanner 逐行讀取文件,避免一次性加載整個文件到內存中的問題。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/EhipkDxyTt3uHnxmNI7O0A