问题:
我正在使用监视服务来监视目录以进行输入,因此一旦我有两个(半)匹配的输入文件,我就可以触发一个事件。我遇到的问题是:如果我有两个列表,每个列表包含可能不同的字符串,我怎样才能在列表发现时找到匹配的根。
文件名结构如下所示:
<companyname>-<ordernum><postfix>.csv
所以例如:
list1 could contain:
mycomp-1234.csv
mycomp-4567.csv
newcomp-7891.csv
oldcomp-3376.csv
list2 could contain:
mycomp-2232_items.csv
newcomp-13123_items.csv
oldcomp-87078777_items.csv
mycomp-1234_items.csv
我想找到,并在列表之间发生匹配时立即触发事件。匹配是任何文件名,少于后缀。即mycomp-1234将返回两个列表的匹配。
我在寻找什么
我希望找到最有效的方式来做到这一点。我知道我可以迭代每个列表比较值,但我相信有更有效的方法来做到这一点。
我不需要代码,我宁愿自己学习,所以推动正确的方向是完美的。如果你的手指让你编写代码,请编写伪代码,以便它可以使尽可能多的语言受益。
不,这不是功课。对于那些非常好奇的人来说,这是执行从csv到X12 EDI文件的EDI转换。
答案 0 :(得分:3)
按字母顺序对列表进行排序,然后比较值并在列表中具有较小值的步骤中前进。如果列表中有任何共同的元素,则值将匹配。
答案 1 :(得分:2)
两个排序列表的并排比较。
Collections.sort(list1);
Collections.sort(list2);
int i1 = 0;
int i2 = 0;
while (i1 < list1.size() && i2 < list.size()) {
String name1 = list1.get(i1);
String name2 = list2.get(i2);
String[] parts1 = name1.split("[-_.]");
String[] parts2 = name2.split("[-_.]");
if (parts1.length < 3) {
++i1;
continue;
}
if (parts2.length < 3) {
++i2;
continue;
}
int cmp = parts1[0].compareTo(parts1[0]);
if (cmp == 0) {
cmp = parts1[1].compareTo(parts1[1]);
}
if (cmp < 0) {
++i1;
continue
}
if (cmp > 0) {
++i2;
continue
}
// Found match:
...
++i1;
++i2;
}
答案 2 :(得分:-1)
在线方法:维护包含所有当前文件名的二叉搜索树。用作文件名相关位的键。例如,newcomp-7891.csv
或newcomp-7891_items
的密钥为newcomp-7891
。每次监视服务报告目录事件时,您都可以删除废弃的名称,并可以尝试向树中添加新名称。如果某个密钥已在树中,则触发您想要的活动。
如果散列实现支持在删除文件名时删除密钥,则可以类似地使用散列表。
这个问题要求“以最有效的方式做到这一点”。请注意,此方法比每次发生目录事件时从头开始排序列表更有效。在具有k个添加和删除的事件中,如果数据集具有n个条目,则它使用O(k·lg n)时间,因此在u目录事件中,在平均树大小为n并且发生m添加/删除的一段时间内,它会做O(m·lg n)工作。相比之下,在其他答案中建议的排序 - 每次方法将做O(u·n·lg n)工作,这是更多。