[英]Finding set of elements common in set of arrays
假设有几个数组:
A. [1,2,3,4,5,6,7,8,9,10]
B. [2,4,6,8,10]
C. [1,4,7,10]
D. [1,3,5,7,9]
.
.
我需要找出所有可能的元素集(1,2,3,4,5 ...),每个元素在至少2个数组(A,B,C ....)中是常见的,并在其中显示如下方式:
(2,4,6,8,10) -> (A,B)
(1,4,7,10) -> (A,C)
(1,3,5,7,9) -> (A,D)
(4,10) -> (A,B,C)
(1,7) -> (A,C,D)
实际输入是包含字符串的文件。 可能有成千上万个文件,每个文件可能包含一百多个密钥字符串。
我尝试了以下方法:首先,我通过比较所有可能的数组对来生成元素集。 然后,我尝试使用逻辑生成其他集合-元素集的相交在数组集的并集中很常见。 像这样:
(2,4,6,8,10) -> (A,B)
(1,4,7,10) -> (A,C)
从上面我们可以得到:
intersect((2,4,6,8,10),(1,4,7,10)) -> union((A,B),(A,C))
or, (4,10) -> (A,B,C)
还有什么我可以尝试改善时间和内存复杂性的方法-考虑千个输入文件,每个文件包含数百个元素?
我将使用以下方法。
使用哈希图(或地图,如果您需要担心碰撞)。 伪代码如下:
for file in file_list:
for word in file:
hash_map[word].append(file)
for wordkey in hash_map:
print pick_uniques(hash_map[wordkey])
这种方法具有复杂度O(单词总数),而忽略了每个单词的长度。
编辑:由于您还希望将wordkey
与相同的pick_uniques(hash_map[wordkey])
组合在一起,因此您可以应用相同的hash-map方法,这一次是将键反转。
这个Java类:
public class Store {
Map<Integer,Set<String>> int2keyset = new HashMap<>();
Set<Set<String>> setOfKeyset = new HashSet<>();
public void enter( String key, Integer[] integers ){
for( Integer val: integers ){
Set<String> keySet = int2keyset.get( val );
Set<String> newKeySet = null;
if( keySet == null ){
newKeySet = new HashSet<String>();
newKeySet.add( key );
} else {
newKeySet = new HashSet<>( keySet );
newKeySet.add( key );
}
setOfKeyset.remove( newKeySet );
setOfKeyset.add( newKeySet );
int2keyset.put( val, newKeySet );
}
}
public void dump(){
Map<Set<String>,Set<Integer>> keySet2intSet = new HashMap<>();
for( Map.Entry<Integer,Set<String>> entry: int2keyset.entrySet() ){
Integer intval = entry.getKey();
Set<String> keySet = entry.getValue();
Set<Integer> intSet = keySet2intSet.get( keySet );
if( intSet == null ){
intSet = new HashSet<Integer>();
}
intSet.add( intval );
keySet2intSet.put( keySet,intSet );
}
for( Map.Entry<Set<String>,Set<Integer>> entry: keySet2intSet.entrySet() ){
System.out.println( entry.getValue() + " => " + entry.getKey() );
}
}
}
当喂入问题中给出的行时,将产生:
[2, 6, 8] => [A, B]
[3, 5, 9] => [A, D]
[4, 10] => [A, B, C]
[1, 7] => [A, C, D]
尽管它与预期输出不完全相同,但它确实包含产生该结果的所有信息,并且更加紧凑。 如果预期会有大量的输入行,那么可能值得追求一种使存储的信息尽可能紧凑的方法,我已经尝试遵循该指南。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.