我正在开发一个项目,我必须解析一个文本文件并将字符串分成用户指定长度的子字符串。然后我需要检测结果中的重复项。
所以原始文件看起来像这样:
ORIGIN
1 gatccaccca tctcggtctc ccaaagtgct aggattgcag gcctgagcca ccgcgcccag
61 ctgccttgtg cttttaatcc cagcactttc agaggccaag gcaggcgatc agctgaggtc
121 aggagttcaa gaccagcctg gccaacatgg tgaaacccca tctctaatac aaatacaaaa
181 aaaaaacaaa aaacgttagc caggaatgag gcccggtgct tgtaatccta aggaaggaga
241 ccaccactcc tcctgctgcc cttcccttcc ccacaccgct tccttagttt ataaaacagg
301 gaaaaaggga gaaagcaaaa agcttaaaaa aaaaaaaaaa cagaagtaag ataaatagct
我遍历文件并生成一行字符串,然后使用line.toCharArray()
滑过结果行并根据用户规范进行划分。因此,如果子串长度为4,结果将如下所示:
GATC
ATCC
TCCA
CCAC
CACC
ACCC
CCCA
CCAT
CATC
ATCT
TCTC
CTCG
TCGG
CGGT
GGTC
GTCT
TCTC
CTCC
TCCC
CCCA
CCAA
以下是我拆分的代码:
try {
scanner = new Scanner(toSplit);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
char[] chars = line.toCharArray();
for (int i = 0; i < chars.length - (k - 1); i++) {
String s = "";
for(int j = i; j < i + k; j++) {
s += chars[j];
}
if (!s.contains("N")) {
System.out.println(s);
}
}
}
}
我的问题是:鉴于输入文件可能很大,我如何检测结果中的重复项?
答案 0 :(得分:0)
如果要检查重复项,则Set是保存和测试数据的不错选择。请告诉您要在哪个上下文中检测重复项:单词,行或“输出字符”。
答案 1 :(得分:0)
你可以这样做:
Map<String, Integer> substringMap = new HashMap<>();
int index = 0;
Set<String> duplicates = new HashSet<>();
对于您从文件中提取的每个substring
,只有在不重复的情况下才将其添加到substringMap
(如果它是重复的,则将其添加到duplicates
):< / p>
if (substringMap.putIfAbsent(substring, index) == null) {
++index;
} else {
duplicates.add(substring);
}
然后,您可以轻松地拉出所有子字符串:
String[] substringArray = new String[substringMap.size()];
for (Map.Entry<String, Integer> substringEntry : substringMap.entrySet()) {
substringArray[substringEntry.getValue()] = substringEntry.getKey();
}
瞧!原始顺序的输出数组,没有重复,加上一组重复的子串,性能非常好。
答案 2 :(得分:0)
您可以使用bloom filter或哈希表来检测可能的重复项,然后对文件进行第二次传递,以检查这些&#34;重复的候选者&#34;是不是真的重复。
哈希表的示例:
// First we make a list of candidates so we count the times a hash is seen
int hashSpace = 65536;
int[] substringHashes = new int[hashSpace];
for (String s: tokens) {
substringHashes[s.hashCode % hashSpace]++; // inc
}
// Then we look for words that have a hash that seems to be repeated and actually see if they are repeated. We use a set but only of candidates so we save a lot of memory
Set<String> set = new HashSet<String>();
for (String s: tokens) {
if (substringHashes[s.hashCode % hashSpace] > 1) {
boolean repeated = !set.add(s);
if (repeated) {
// TODO whatever
}
}
}