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