• 请不要在回答技术问题时复制粘贴 AI 生成的内容
1ven
V2EX  ›  程序员

如何实现检查一个大 txt 文件里数据是否重复的功能

  •  
  •   1ven · Feb 27, 2024 · 6882 views
    This topic created in 989 days ago, the information mentioned may be changed or developed.

    如何实现检查一个大 txt 文件里数据是否重复的功能

    如题,文件的每一行数据结构都是相同的,字段值通过一个自定义分隔符分割。比如有如下结构数据,id|name|bizNo ,检查 id 是否重复。

    最好是 java 实现的
    49 replies  •  2024-02-29 23:14:33 +08:00
    GeruzoniAnsasu
    GeruzoniAnsasu
    Feb 27, 2024
    1
    你们 java 八股不是很喜欢考 hashmap 来着
    Rickkkkkkk
    Rickkkkkkk
    Feb 27, 2024❤️1
    2
    @GeruzoniAnsasu 八股文考的一般是内存里存不下, 比如文件是 1T 大小
    HojiOShi
    HojiOShi
    Feb 27, 2024
    3
    要检查一个包含重复数据的文本文件中的数据是否重复,你可以按照以下步骤进行:

    使用 BufferedReader 和文件流读取文件内容。
    将每行内容分割为字段,这里使用你提供的自定义分隔符 | 作为字段间分隔符。
    使用哈希表(或 HashSet )来存储每个字段的值。
    遍历每个字段的值,如果已经在哈希表中存在该值,则说明数据重复,否则将该值添加到哈希表中。
    检查哈希表的大小,如果大小大于预期 Repeat Count ,则说明数据存在重复。
    下面是一个 Java 示例代码,你可以根据自己的需求进行修改:

    import java.io.*;
    import java.util.HashMap;
    import java.util.Map;

    public class CheckDuplicateData {
    public static void main(String[] args) throws IOException {
    String fileName = "data.txt"; // 文件名
    String delimiter = "|"; // 自定义分隔符
    int repeatCount = 2; // 预期的重复次数

    Map<String, Integer> countMap = new HashMap<>(); // 统计每个字段的值出现的次数

    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
    String line;
    while ((line = br.readLine()) != null) {
    String[] fields = line.split(delimiter); // 分割每行为字段
    for (String field : fields) {
    if (!countMap.containsKey(field)) {
    countMap.put(field, 0);
    }
    countMap.put(field, countMap.get(field) + 1);
    }
    if (countMap.size() > repeatCount) {
    System.out.println("数据存在重复");
    break;
    }
    }
    }
    }
    }

    在上面的示例代码中,我们使用了 HashMap 来统计每个字段的值出现的次数。在遍历文件内容时,对于每个字段,我们首先检查是否已经存在于哈希表中,如果不存在,则将其添加到哈希表中并记录计数;如果已经存在于哈希表中,则将计数加一。最后,检查哈希表的大小是否大于预期重复次数,如果是,则输出提示信息并退出循环。
    mubai
    mubai
    Feb 27, 2024
    4
    遍历大 txt 并按照 id 取模拆分成多个小 txt ,读取小 txt 在内存中判断重复。
    zihuyishi
    zihuyishi
    Feb 27, 2024
    5
    印象中这种问题是分组吧,按照首字母或者什么方式 hash 一下分成 n 个小文件,然后再小文件内依次检查是否有重复的
    maoyikun
    maoyikun
    Feb 27, 2024
    6
    Java 的 NIO 随机读取文件 RandomAccessFile 应该可以满足需求
    Jirajine
    Jirajine
    Feb 27, 2024❤️1
    7
    用 txt 存储大体量的数据是很少见的场景,只在一些传播的裤子中见到过。
    正常来说需要对这种数据进行清洗分析之前最好先导入到正经的数据库里。
    tutudou
    tutudou
    Feb 27, 2024
    8
    这个我写过类似的,是大文本分割,无论文本多大不经过内存,通过文件指针的方式直接分割文本。你这个要看具体是多大了,看把所有 ID 加入到内存能不能放的下,如果能放得下直接排序不就得了简单省事。如果放不下,考虑要不炫技使用文件指针的骚方式解决。要不把所有数据存入数据库,把 ID 设为唯一且不重复。
    yuruizhe
    yuruizhe
    Feb 27, 2024
    9
    @Rickkkkkkk 如果 id 是整数,用一个布尔数组呗,1T 比特内存,切成若干分页文件
    icedx
    icedx
    Feb 27, 2024
    10
    前年用 rust 写过一个, 卖了 2K XD
    NESeeker
    NESeeker
    Feb 28, 2024 via Android❤️1
    11
    裤子?
    xarthur
    xarthur
    Feb 28, 2024 via iPhone
    12
    既然是大文件,首先第一个问题就是多大……
    levelworm
    levelworm
    Feb 28, 2024 via Android
    13
    数据库行吗?
    nutting
    nutting
    Feb 28, 2024❤️1
    14
    这是需要完美解决的算法题还是一般实际工程问题?
    netnr
    netnr
    Feb 28, 2024 via Android
    15
    布隆过滤器

    如果结果不准确,增强或多个 Hash 计算
    dode
    dode
    Feb 28, 2024
    16
    先用 HashSet 存看看,不够再说
    miniliuke
    miniliuke
    Feb 28, 2024
    17
    直接布个 spark 集群,文件大就加机器......
    gitdoit
    gitdoit
    Feb 28, 2024
    18
    简单点 用 SQLite
    silencil
    silencil
    Feb 28, 2024
    19
    这没说到底多大的文件啊,简单点 map 计数都行,实在大的离谱不得搭个大数据框架 mapreduce 下:) doge
    bookerlevit
    bookerlevit
    Feb 28, 2024
    20
    有一个软件叫“大数据去重复工具”,可以去重复,而且超大文件也可以,他是分段去去重复,最后再整合的。
    layxy
    layxy
    Feb 28, 2024
    21
    使用 BufferedReader 逐行读取,如果只需要排重使用 set 就可以,如果需要重复计数排序可以使用 map
    guanzhangzhang
    guanzhangzhang
    Feb 28, 2024
    22
    @icedx #10 2K XD 是啥意思
    o562dsRcFqYl375i
    o562dsRcFqYl375i
    Feb 28, 2024
    23
    要不咋们跳出单机器的思维,spark 一下?
    o562dsRcFqYl375i
    o562dsRcFqYl375i
    Feb 28, 2024
    24
    @nutting 还是老哥想的周全
    Greenm
    Greenm
    Feb 28, 2024
    25
    经常接触过这样的需求,如果不考虑一定要原始文件中字符的顺序,我的选择是 Linux 上的 sort | uniq ,流式处理速度非常快。
    dushixiang
    dushixiang
    Feb 28, 2024❤️2
    26
    1ven
    1ven
    OP
    Feb 28, 2024
    27
    @FreeEx 上次我也看到过有人发过这个链接,就是找不到了,老哥知道原贴吗
    815979670
    815979670
    Feb 28, 2024
    28
    duckDB 读入 用 SQL 查询出来?
    Subfire
    Subfire
    Feb 28, 2024
    29
    用正则匹配重复行即可:
    ^(.+?)$(?=.*?^\1$)
    fuis
    fuis
    Feb 28, 2024
    30
    一行脚本可解

    ```
    [ $(cat 1.txt | wc -l) = $(cat 1.txt | awk -F, '{print $1}' | sort -n | uniq | wc -l) ]; echo $?
    ```
    beyondstars
    beyondstars
    Feb 28, 2024
    31
    可以用 trie tree (也叫前缀树)来实现,将文本文件打开为一个 stream, 把这个 stream pipe 到一个 trie tree 型对象里面,每一个 insert 之后返回对应节点的指针,然后检查该节点的 count 是否大于 1.
    beyondstars
    beyondstars
    Feb 28, 2024
    32
    伪代码如下:

    let trieTree = new TrieTree();
    let lineStream = openStream("data.txt");
    while lineStream is not EOF:
    let line = lineStream.getLine();
    let field1Value = split(line)[0];
    let lastNode = trieTree.insert(field1Value);
    if (lastNode.count > 1)
    print("Repeated.")
    return
    beyondstars
    beyondstars
    Feb 28, 2024
    33
    不过 trieTree 的 insert 操作一般接受的是一个 path ,你把 string 转换成 char[] 再 insert 到 trieTree ,这样 string 也可以看作是 path 。
    wangtian2020
    wangtian2020
    Feb 28, 2024
    34
    如果不爆内存,我的做法是

    nodejs 读取文件为字符串
    换行符/t 分隔字符串为数组
    数据把 id map 出来
    对数组进行 [...new Set] 变换
    判断变换前后 length 是否一致
    ffw5b7
    ffw5b7
    Feb 28, 2024 via Android
    35
    类似分库分表怎么排序查询 top10 一样处理
    Tiking
    Tiking
    Feb 28, 2024
    36
    老实交代,前几天的上亿裤子,你是不是下完了
    nuII
    nuII
    Feb 28, 2024
    37
    @NESeeker 脱裤,就是数据库
    sud0day
    sud0day
    Feb 28, 2024
    38
    @Jirajine 加一,我一听描述感觉就是 TG 上的社工库
    sankooc
    sankooc
    Feb 28, 2024
    39
    准确率要求高么 不高的话可以考虑 HLL
    ethusdt
    ethusdt
    Feb 28, 2024❤️1
    40
    @beyondstars #31 我想到的也是 Trie 数据结构
    hemingwang0902
    hemingwang0902
    Feb 28, 2024
    41
    @HojiOShi chatGPT 用得很溜
    xxiu
    xxiu
    Feb 28, 2024
    42
    id 如果是数字的话,使用位来表示,1G 可以表示 8589934592 个位置。 只需要一个循环。
    xiaohundun
    xiaohundun
    Feb 28, 2024
    43
    我比较好奇楼上提到的分段去重怎么做到呢
    一段内不重复不代表整个文件不重复,请教下
    chtcrack
    chtcrack
    Feb 28, 2024
    44
    在 Java 中,检查一个大文本文件中数据是否重复可以通过多种方法实现。以下是一种简单的实现方式:
    读取文件中的每一行。
    解析每行数据,提取出 id 字段。
    将提取出的 id 存储到某种数据结构中,例如 HashSet ,以快速检查重复。
    遍历文件,同时检查新读取的 id 是否已经在数据结构中。
    以下是一个简单的 Java 代码示例,演示了如何实现这一功能:
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.HashSet;

    public class CheckDuplicate {
    public static void main(String[] args) {
    String filePath = "path/to/your/file.txt"; // 替换为你的文件路径
    String separator = "|"; // 数据字段之间的分隔符

    HashSet<String> ids = new HashSet<>();
    boolean hasDuplicates = false;

    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
    String line;
    while ((line = br.readLine()) != null) {
    String[] fields = line.split(separator);
    String id = fields[0]; // 假设 id 在第一个字段

    if (ids.contains(id)) {
    System.out.println("Duplicate ID found: " + id);
    hasDuplicates = true;
    } else {
    ids.add(id);
    }
    }
    } catch (IOException e) {
    e.printStackTrace();
    }

    if (!hasDuplicates) {
    System.out.println("No duplicates found.");
    }
    }
    }
    在这个代码示例中,我们使用了 HashSet 来存储所有唯一的 id ,因为 HashSet 提供了 O(1)的时间复杂度来检查一个元素是否存在于集合中。这使得检查重复变得非常高效。
    请注意,这个代码示例没有进行详细的错误处理,实际应用中可能需要添加更多的异常处理和资源管理代码。此外,根据您的文件大小和内存限制,可能需要考虑使用更高效的数据结构或读取文件的部分内容以避免内存溢出。
    tyrone2333
    tyrone2333
    Feb 28, 2024
    45
    @guanzhangzhang #22 2K 金额 XD 笑
    Akiya
    Akiya
    Feb 29, 2024
    46
    没爆内存就 set 存,爆内存就放数据库查
    lslqtz
    lslqtz
    Feb 29, 2024
    47
    实现一个 func, 以一定的 buffer 顺序读文件, buffer 长度要大于最长匹配词长度的 2 倍, 做匹配, 若匹配到存 offset 或直接返回 bool.
    lslqtz
    lslqtz
    Feb 29, 2024
    48
    哦, 我以为是匹配给定 keyword 呢, 匹配规律的小数据的话也可以从头读到尾提出来匹配.
    Rorysky
    Rorysky
    Feb 29, 2024
    49
    sort *.txt | uniq -d
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4589 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 96ms · UTC 06:29 · PVG 14:29 · LAX 22:29 · JFK 01:29
    ♥ Do have faith in what you're doing.