需要解决以下问题:
根据以下标准将唯一字符串集拆分为不重叠的组:
如果两行在一列或多列中有匹配的非空值,则它们属于同一组。
例如,线条
111;123;222 200;123;100 300;;100都属于同一个组,因为前两行在第二列中具有相同的值,而后两行在第三列中
123具有相同的值100
程序运行时间(30 秒)也有限制。我还可以添加行数——大约一百万。这是我的代码:
private static Set<TreeSet<Integer>> findLineGroups(List<String> lines) {
Set<TreeSet<Integer>> resultSet = new TreeSet<>((Comparator<TreeSet<Integer>>) (trSet1, trSet2) -> {
int diff = trSet2.size() - trSet1.size();
if (diff != 0)
return diff;
Iterator<Integer> iterator1 = trSet1.iterator();
Iterator<Integer> iterator2 = trSet2.iterator();
while (iterator1.hasNext()) {
diff = iterator1.next() - iterator2.next();
if (diff != 0)
return diff;
}
return 0;
});
Map<String, Integer> termLineGroupsPairs = new HashMap<>();
List<TreeSet<Integer>> lineNumGroups = new ArrayList<>();
for (int lineNum = 0; lineNum < lines.size(); lineNum++) {
String line = lines.get(lineNum);
String[] lineElements = line.replaceAll("\"", "").replaceAll(" ", "").split(";");
Set<String> termSet = new HashSet<>(Arrays.asList(lineElements));
termSet.remove("");
Integer groupNum = null;
TreeSet<String> tempSet = new TreeSet<>(termLineGroupsPairs.keySet());
tempSet.retainAll(termSet); //оставляем только общие элементы
if (!tempSet.isEmpty()) {
String term = tempSet.first();
groupNum = termLineGroupsPairs.get(term);
lineNumGroups.get(groupNum).add(lineNum);
}
if (groupNum == null) {
TreeSet<Integer> group = new TreeSet<>();
group.add(lineNum);
lineNumGroups.add(group);
groupNum = lineNumGroups.size() - 1;
}
for (String term : termSet) {
termLineGroupsPairs.put(term, groupNum);
}
if (lineNumGroups.size() % 1000 == 0)
System.out.println(lineNumGroups.size());
}
resultSet.addAll(lineNumGroups);
return resultSet;
}
而且我所有的解决方案都工作太久(我试图以不同的方式解决这个问题)。诚然,如果少于一千行,那么它可以快速运行(我符合指定的限制),并且几乎可以使用我的任何算法。
请告诉我如何解决这个问题(或在我的解决方案中进行哪些更改以使其快速运行)。
我得出了“几乎在额头上”的解决方案:
[номер_группы -> [строки_группы]][позиция_слова -> { слово -> номер_группы }]null不移动列表内的元素)比文字更多的代码出现:
也许我的电脑太快了,无法“按他们应该”测试工作速度,但是对于一百万行,每行由 5 个单词组成,每个单词又由 5 个英文字母的小写字母组成,执行时间约为 4 秒。
有这样一个数据结构——不相交集的森林(disjoint sets union)。它的排列非常简单,并且可以让您快速组合相关元素。
在这种情况下,如果我们忽略关于需要匹配列号的语句,则每个集合(组)必须包含类型为 123 等元素的哈希表(映射)。
每个新行都被划分为元素,并检查这些元素在现有组中的存在。
- 如果没有元素匹配,则创建一个新组。
- 如果有一个匹配,则将该行添加到该组中。
- 如果有两个或更多 - 线用作连接组的链接 - 它们被组合,并且线被添加到组合组中。
在考虑列数的情况下,设定最大列数对应的map数,在每个map中进行搜索。