1 GeruzoniAnsasu 2024-02-27 19:33:10 +08:00 你们 java 八股不是很喜欢考 hashmap 来着 |
2 Rickkkkkkk 2024-02-27 19:34:26 +08:00 ![]() @GeruzoniAnsasu 八股文考的一般是内存里存不下, 比如文件是 1T 大小 |
![]() | 3 HojiOShi 2024-02-27 19:45:00 +08:00 要检查一个包含重复数据的文本文件中的数据是否重复,你可以按照以下步骤进行: 使用 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 来统计每个字段的值出现的次数。在遍历文件内容时,对于每个字段,我们首先检查是否已经存在于哈希表中,如果不存在,则将其添加到哈希表中并记录计数;如果已经存在于哈希表中,则将计数加一。最后,检查哈希表的大小是否大于预期重复次数,如果是,则输出提示信息并退出循环。 |
![]() | 4 mubai 2024-02-27 19:50:44 +08:00 遍历大 txt 并按照 id 取模拆分成多个小 txt ,读取小 txt 在内存中判断重复。 |
5 zihuyishi 2024-02-27 19:58:38 +08:00 印象中这种问题是分组吧,按照首字母或者什么方式 hash 一下分成 n 个小文件,然后再小文件内依次检查是否有重复的 |
6 maoyikun 2024-02-27 20:00:37 +08:00 Java 的 NIO 随机读取文件 RandomAccessFile 应该可以满足需求 |
7 Jirajine 2024-02-27 20:11:01 +08:00 ![]() 用 txt 存储大体量的数据是很少见的场景,只在一些传播的裤子中见到过。 正常来说需要对这种数据进行清洗分析之前最好先导入到正经的数据库里。 |
8 tutudou 2024-02-27 20:30:24 +08:00 这个我写过类似的,是大文本分割,无论文本多大不经过内存,通过文件指针的方式直接分割文本。你这个要看具体是多大了,看把所有 ID 加入到内存能不能放的下,如果能放得下直接排序不就得了简单省事。如果放不下,考虑要不炫技使用文件指针的骚方式解决。要不把所有数据存入数据库,把 ID 设为唯一且不重复。 |
9 yuruizhe 2024-02-27 21:41:02 +08:00 @Rickkkkkkk 如果 id 是整数,用一个布尔数组呗,1T 比特内存,切成若干分页文件 |
![]() | 10 icedx 2024-02-27 21:52:51 +08:00 前年用 rust 写过一个, 卖了 2K XD |
11 NESeeker 2024-02-28 01:13:19 +08:00 via Android ![]() 裤子? |
![]() | 12 xarthur 2024-02-28 01:34:37 +08:00 via iPhone 既然是大文件,首先第一个问题就是多大…… |
![]() | 13 levelworm 2024-02-28 03:10:48 +08:00 via Android 数据库行吗? |
![]() | 14 nutting 2024-02-28 08:41:58 +08:00 ![]() 这是需要完美解决的算法题还是一般实际工程问题? |
![]() | 15 netnr 2024-02-28 08:57:10 +08:00 via Android 布隆过滤器 如果结果不准确,增强或多个 Hash 计算 |
16 dode 2024-02-28 09:06:57 +08:00 先用 HashSet 存看看,不够再说 |
17 miniliuke 2024-02-28 09:07:59 +08:00 直接布个 spark 集群,文件大就加机器...... |
18 gitdoit 2024-02-28 09:13:36 +08:00 简单点 用 SQLite |
19 silencil 2024-02-28 09:22:01 +08:00 这没说到底多大的文件啊,简单点 map 计数都行,实在大的离谱不得搭个大数据框架 mapreduce 下:) doge |
![]() | 20 bookerlevit 2024-02-28 09:27:19 +08:00 有一个软件叫“大数据去重复工具”,可以去重复,而且超大文件也可以,他是分段去去重复,最后再整合的。 |
21 layxy 2024-02-28 09:29:23 +08:00 使用 BufferedReader 逐行读取,如果只需要排重使用 set 就可以,如果需要重复计数排序可以使用 map |
![]() | 22 guanzhangzhang 2024-02-28 09:36:19 +08:00 @icedx #10 2K XD 是啥意思 |
23 o562dsRcFqYl375i 2024-02-28 09:39:34 +08:00 要不咋们跳出单机器的思维,spark 一下? |
24 o562dsRcFqYl375i 2024-02-28 09:41:25 +08:00 @nutting 还是老哥想的周全 |
25 Greenm 2024-02-28 09:43:21 +08:00 经常接触过这样的需求,如果不考虑一定要原始文件中字符的顺序,我的选择是 Linux 上的 sort | uniq ,流式处理速度非常快。 |
![]() | 26 FreeEx 2024-02-28 09:50:47 +08:00 ![]() |
![]() | 28 815979670 2024-02-28 10:27:47 +08:00 duckDB 读入 用 SQL 查询出来? |
![]() | 29 Subfire 2024-02-28 10:51:33 +08:00 用正则匹配重复行即可: ^(.+?)$(?=.*?^\1$) |
![]() | 30 fuis 2024-02-28 11:06:18 +08:00 一行脚本可解 ``` [ $(cat 1.txt | wc -l) = $(cat 1.txt | awk -F, '{print $1}' | sort -n | uniq | wc -l) ]; echo $? ``` |
![]() | 31 beyondstars 2024-02-28 11:15:23 +08:00 可以用 trie tree (也叫前缀树)来实现,将文本文件打开为一个 stream, 把这个 stream pipe 到一个 trie tree 型对象里面,每一个 insert 之后返回对应节点的指针,然后检查该节点的 count 是否大于 1. |
![]() | 32 beyondstars 2024-02-28 11:22:12 +08:00 伪代码如下: 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 |
![]() | 33 beyondstars 2024-02-28 11:24:01 +08:00 不过 trieTree 的 insert 操作一般接受的是一个 path ,你把 string 转换成 char[] 再 insert 到 trieTree ,这样 string 也可以看作是 path 。 |
![]() | 34 wangtian2020 2024-02-28 11:39:06 +08:00 如果不爆内存,我的做法是 nodejs 读取文件为字符串 换行符/t 分隔字符串为数组 数据把 id map 出来 对数组进行 [...new Set] 变换 判断变换前后 length 是否一致 |
35 ffw5b7 2024-02-28 11:44:06 +08:00 via Android 类似分库分表怎么排序查询 top10 一样处理 |
![]() | 36 Tiking 2024-02-28 11:49:56 +08:00 老实交代,前几天的上亿裤子,你是不是下完了 |
![]() | 39 sankooc 2024-02-28 15:34:34 +08:00 准确率要求高么 不高的话可以考虑 HLL |
![]() | 40 ethusdt 2024-02-28 15:49:48 +08:00 ![]() @beyondstars #31 我想到的也是 Trie 数据结构 |
41 hemingwang0902 2024-02-28 16:17:54 +08:00 @HojiOShi chatGPT 用得很溜 |
![]() | 42 xxiu 2024-02-28 16:45:04 +08:00 id 如果是数字的话,使用位来表示,1G 可以表示 8589934592 个位置。 只需要一个循环。 |
![]() | 43 xiaohundun 2024-02-28 16:58:43 +08:00 我比较好奇楼上提到的分段去重怎么做到呢 一段内不重复不代表整个文件不重复,请教下 |
44 chtcrack 2024-02-28 17:04:51 +08:00 在 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)的时间复杂度来检查一个元素是否存在于集合中。这使得检查重复变得非常高效。 请注意,这个代码示例没有进行详细的错误处理,实际应用中可能需要添加更多的异常处理和资源管理代码。此外,根据您的文件大小和内存限制,可能需要考虑使用更高效的数据结构或读取文件的部分内容以避免内存溢出。 |
![]() | 45 tyrone2333 2024-02-28 17:05:11 +08:00 @guanzhangzhang #22 2K 金额 XD 笑 |
![]() | 46 Akiya 2024-02-29 10:55:14 +08:00 没爆内存就 set 存,爆内存就放数据库查 |
![]() | 47 lslqtz 2024-02-29 18:17:42 +08:00 实现一个 func, 以一定的 buffer 顺序读文件, buffer 长度要大于最长匹配词长度的 2 倍, 做匹配, 若匹配到存 offset 或直接返回 bool. |
![]() | 48 lslqtz 2024-02-29 18:19:42 +08:00 哦, 我以为是匹配给定 keyword 呢, 匹配规律的小数据的话也可以从头读到尾提出来匹配. |
![]() | 49 Rorysky 2024-02-29 23:14:33 +08:00 sort *.txt | uniq -d |