我有一个数组数组。 例如:
[
[a, b, c],
[b, d],
[a, c],
[b],
[a, b, c, d]
]
实际上,内部数组相对较短,但外部数组将是几千行。
现在,我有一个参考数组。 例如:
[a, b, c]
挑战在于确定第一个数组的哪些行完全包含在引用数组中。对于这个例子,我希望在检查之后将行1,3和4返回给我。
我可以很容易地使用嵌套循环来做到这一点,但我想知道是否有一个更加可扩展的聪明算法。
回顾:我需要行号作为参考数组的某个子集。行元素不一定是唯一的。 编辑:每个阵列中有大约200个独特的元素。数组数组将是常量,但我需要对许多不同的引用数组执行相同的搜索
答案 0 :(得分:2)
如果将参考数组存储为可以在O(1)时间内检查元素成员资格的结构(例如,由于Universe很小,使用哈希表或仅使用0/1成员指示符数组),然后你可以将你的数组集合存储为每个数组排序的trie,并遍历trie查找路径到完全包含在引用数组中的叶子。这可以降低复杂性,因为当子集合中的数组重叠时,您将使用trie中较高的单个比较同时遍历数组的子集合,并且当它们包含数组时,您将同时跳过数组的子集不在参考数组中的公共元素。
答案 1 :(得分:0)
如果你需要为同一个数组阵列多次执行此操作,除了short之外的内部数组还有一组非可能的元素,并且它们从不具有重复元素(感谢@Kunukn),你可以创建一个替代结构,将内部数组转换为数字并执行" XOR"和"或"要找到的元素和数组之间。这样,您只需将数组循环一次。此外,您可以按值对数组数组进行排序,这可能对其他用途有用。 示例:a为1,b为2,c为4,d为8.您的数组样本数组变为:
[
[a, b, c], // 1 + 2 + 4 == 7
[b, d], // 2 + 8 == 10
[a, c], // 1 + 4 == 5
[b], // 2 == 2
[a, b, c, d] // 1 + 2 + 4 + 8 == 15
]
然后,您的引用数组[a, b, c]
计算为7,与上述数组数组中的第1个元素的计算方式相同。现在,搜索元素。假设有一个4位整数来表示它们,你有:
7 XOR 7 => 1110 XOR 1110 == 0000; 0000 OR 1110 == 1110 => equal to 7, found
10 XOR 7 => 0101 XOR 1110 == 1011; 1011 OR 1110 == 1111 => not equal to 7, not found
5 XOR 7 => 1010 XOR 1110 == 0100; 0100 OR 1110 == 1110 => equal to 7, found
2 XOR 7 => 0100 XOR 1110 == 1010; 1010 OR 1110 == 1110 => equal to 7, found
15 XOR 7 => 1111 XOR 1110 == 0001; 0001 OR 1110 == 1111 => not equal to 7, not found
编辑:即使您没有使用200位的整数,您仍然可以使用200位结构并执行相同的操作,这对您来说只是更多的工作。
答案 2 :(得分:0)
您可以使用子集匹配。 我假设您的数据集已经过排序。
从参考数组构建子集可能性。如果参考数组很小,那么最好,否则要构建和比较的数据集将是大的。
E.g。参考数组[a, b, c]
的已排序子集匹配给出
[a], [b], [c], [a,b], [a,c], [b,c], [a,b,c]
来自数据集
[
[a, b, c],
[b, d],
[a, c],
[a, c],
[b],
[a, b, c, d]
]
使用数组中的位置
构建数据的哈希表 hash table
"abc", [1]
"bd", [2]
"ac", [3,4]
"b", [5]
"abcd", [6]
引用数组哈希
hashReference = {"a","b","c","ab", "ac," "bc", "abc"}
算法
foreach key in hashRefence
lookup the hash table
这会返回[5], [3,4], [1]