关于这个话题,我已经尝试了所有其他问题和答案,但我还没有设法让它发挥作用。
我有一个特别排序的字符串列表,例如:["serviceT", "servicC", "serviceA", ... "serviceZ"]
。
我有另一个同名jar文件的完整路径列表:
["C:\Users\USER\projects .... \serviceB-1.0-SNAPSHOT.jar" ...]
。此列表完全无序。此列表使用以下内容生成:
servicesPaths = Files.walk(Paths.get(parentFolder))
.map(Path::toString)
.filter(path -> {
boolean flag = false;
for (String service : services)
if (path.endsWith(version + ".jar") && path.contains(service)) flag = true;
return flag;
})
.collect(Collectors.toList());
基本上我只是给它一个父文件夹,它返回包含service
的所有路径的列表。两个列表的大小相同。我的意思是,每个service
只有一个path
。
我需要订购servicePath
列表,以便它与services
有序列表的顺序相同。
我已经尝试过使用我能想到的各种排序/比较方法,并且只能使用非常粗暴的for循环来实现它:
List<String> temp = new ArrayList<>();
for (String service : services)
for (String path : servicesPaths)
if (path.indexOf(service) > 0)
temp.add(path);
还有其他明智的方法可以对servicePaths
列表进行排序吗?
答案 0 :(得分:1)
第一个优化:由于两个列表的大小相同,因此添加后可以删除路径。这减少了外循环每次运行的内循环次数。
但是我会做什么:改变生成该路径列表的方式。你看:首先你已经有了另一个N * N.然后另一个N * N后来一个?!
相反:
Map<String, Integer>
:key是字符串,重视服务列表中的索引 应该足以让你前进 - 我想你将不得不仔细研究诸如“列表大小真正相同”之类的约束等等(如果你的路径少于服务,那么中间列表可能包含一些空槽然后你必须删除)。
答案 1 :(得分:1)
一个非常直接的解决方案,但我认为这是合适的:
List<String> services = Arrays.asList("serviceA", "serviceC", "serviceB");
List<String> servicesPaths = Arrays.asList("serviceA-bla-bla", "serviceB-bla-bla", "serviceC-bla-bla");
List<String> sortedServices = servicesPaths.stream()
.sorted((a, b) -> Integer.compare(
services.indexOf(a.substring(0, a.indexOf("-"))),
services.indexOf(b.substring(0, b.indexOf("-")))))
.collect(Collectors.toList());
子字符串部分只是从路径中提取服务名称。如果你有任何其他方法,只需用其他方式替换它。
另外,我会通过将比较函数存储在变量中来改进此片段:
Function<String, Integer> indexInServices = path -> services.indexOf(path.substring(0, path.indexOf("-")));
List<String> orderedServices = servicesPaths.stream()
.sorted(Comparator.comparing(indexInServices))
.collect(Collectors.toList());
答案 2 :(得分:1)
按字符串“servicesPaths
”
Service
让 m 大小为servicesPath
让 n 为已排序字符串的大小。
然后使用伪代码
for each string in servicesPath
search SortedStrings by binary search
此解决方案是时间 O(m log(n))* 因为二进制搜索是命令 O(log n)
你的暴力解决方案是时间* O(m * n)*
排序路径的大小是否应小于排序字符串的大小 创建一个记录数组。 (注意,这不是海报的情况。)
class Pair {
String str;
int pos;
}
Pair []Pairs;
Pairs = new Pair[sorted strings.length];
对于排序字符串中的每个项目,将字符串复制到Pair[i]s.str
和
其序号位置为Pairs[i].pos
然后,使用简单的比较器
按Pairs
排序str
然后,对于servicesPaths
中的每个项目,您将获取字符串并执行二进制文件
在Pairs
中。当您找到匹配的那个时,请调用其位置pos
。
将该servicesPaths
项复制到path[pos]
对于CS2(数据结构)类,这是一个很好的练习。
答案 3 :(得分:0)
您可能意识到需要根据require('config.php');
索引进行排序。这是另一种做你需要的方法:
services
答案 4 :(得分:-1)
列表中您称为“已排序”的每个项目(但实际上只是根据某些不透明的标准进行排序)在列表中有一个位置或索引。
这个位置/索引是用于排序其他列表的关键。
对于要排序的列表中的每个元素,在“ordered”列表中查找它,并将找到的元素的索引作为排序键应用。