假设有几个数组:
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)
我是否可以尝试其他方法来改善时间和内存复杂性 - 考虑到每个包含数百个元素的千位输入文件?
答案 0 :(得分:0)
我会使用以下方法。
答案 1 :(得分:0)
使用哈希图(或地图,如果您需要担心碰撞)。下面的伪代码:
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])
结合使用,因此您可以应用相同的哈希映射方法,这次反转键。
答案 2 :(得分:0)
这个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]
虽然它与预期的输出不完全相同,但它确实包含了生成它的所有信息,并且更加紧凑。如果预期会有大量输入行,那么可能值得采用一种方法使存储的信息尽可能紧凑,并且我已尝试遵循此指南。