我是一名Java开发人员,但对于我需要做的特定类型的排序,我还没有找到一个好的算法。
基本上,我将获取从查询返回的一些数据(最多几千行)。我只关心基于单个列的排序。具有讽刺意味的是,该列可能已经排序,但不是以我需要的方式排序。
简单地说就是:
我正在获取一个用户ID列表,我需要对它们进行排序,以便遍历整个列表并重新开始。一个简单的例子比解释容易:
假设数据是这样的:
A,B,C,D,D
对于我的目的,有效的排序顺序为:
A B C D A B D A A
基本上,我需要每个用户在返回之前“转一圈”。可能会有不均匀的用户数量,所以任何额外的用户都会堆叠在最后。
同样,我是用Java做这件事,但在这一点上没有被限制在特定的数据结构中,等等。
附加信息:如果它有帮助,特别是我正在做的是为负载测试生成数据,并希望将同一用户多次登录应用程序的次数降至最低,因此我希望我的测试循环通过所有可用的应用程序用户,然后返回到列表的开头。然而,数据是真实的数据,我不能保证每个用户都有相同数量的活动。
谢谢!汤姆
发布于 2018-09-16 06:28:27
这是我的解决方案。
它不要求输入数据已经排序。
基本上,它使用id和它们出现的次数创建一个Map
,然后循环遍历这个映射,每次选择一个不同的id,直到映射为空。
public static void main(String[] args) {
List<String> ids = Arrays.asList("A", "A", "A", "A", "B", "B", "C", "D", "D");
List<String> idsOrdered = order(ids);
idsOrdered.forEach(System.out::println);
}
private static List<String> order(List<String> ids) {
// create a map with ids and their occurrences
Map<String, Long> occurs = ids.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
List<String> idsOrdered = new ArrayList<>();
while (!occurs.isEmpty()) {
// add all the ids in the map to the list
occurs.forEach((k, v) -> idsOrdered.add(k));
// decrement the counter of all ids
occurs.replaceAll((k, v) -> v - 1);
// remove the ids with the counter at 0
occurs.entrySet().removeIf(e -> e.getValue() == 0);
}
return idsOrdered;
}
下面是相同的解决方案,但是“老派”(没有函数式编程):
private static List<String> order(List<String> ids) {
// create a map with ids and their occurrences
Map<String, Integer> occurs = new HashMap<>();
for (String id : ids) {
Integer occur = occurs.get(id);
if (occur != null) {
occurs.put(id, occur + 1);
}
else {
occurs.put(id, 1);
}
}
List<String> idsOrdered = new ArrayList<>();
while (!occurs.isEmpty()) {
// loop through the map
Iterator<Entry<String, Integer>> it = occurs.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> pair = it.next();
// add the key to the list
String key = pair.getKey();
idsOrdered.add(key);
// update the occurrences, if 0 then remove the id from the map
int newOccur = pair.getValue() - 1;
if (newOccur == 0) {
it.remove();
}
else {
pair.setValue(newOccur);
}
}
}
return idsOrdered;
}
https://stackoverflow.com/questions/52349147
复制相似问题