gpt4 book ai didi

java - 按值排序的 Map 的前 N ​​个值

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:56 25 4
gpt4 key购买 nike

我有一个字符串列表。我想根据返回 double 的函数评估每个字符串。然后我想要前 5 个字符串,基于它们的计算值。如果少于 5 个,我想要全部(按顺序)。假设字符串是化合物,函数计算质量。该函数在计算上很昂贵;我需要对每个字符串进行一次评估。 (不过,我只是在编造数据。)

H2O => 18.5
C12H11O22 => 109.1
HeNe => 32.0
H2SO4 => 54.37
HCl => 19.11
4FeO3 => 82.39
Xe6 => 281.9

程序应返回按各自值顺序排列的前五个字符串。对于此样本数据:H20, HCl, HeNe, H2SO4, 4FeO3 .实际上,我真的不在乎顺序;我只需要任意顺序中最低的五个。

我考虑过如何在 Perl 中执行此操作。这只是几行:

foreach $s (@str) {
$strmap{$s} = f($s);
}
@sorted = sort { $strmap{$a} <=> $strmap{$b} } keys %strmap;
return @sorted[0, 4]

但我需要用 Java 来完成。这让我发疯。

首先我尝试填充 HashMap<String, Double> , 然后使用 Collections.sort使用自定义比较器,就像 Perl 版本一样。但是比较器的范围阻止了它引用 HashMap 来查找值。

然后我尝试了 TreeMap<String, Double> ,但它仅按键排序,任何强制都无法使其按值对条目进行排序。

所以我尝试了 TreeMap<Double, String> .它将丢弃具有相同 Double 的条目。但是,将字符串映射到同一个 Double 的可能性很低,所以我继续前进。将条目添加到 TreeMap 没有问题,但我在尝试从中提取值时遇到了问题。

TreeMap 提供了一个名为 subMap 的方法,但它的参数是分隔子集的键。我不知道它们是什么;我只想要其中的前五个。所以我尝试使用 values方法从 TreeMap 中获取所有值,希望它们是有序的。然后我就可以获得前十个。

ArrayList<String> strs = (ArrayList<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));

没有。运行时错误:无法将 TreeMap$Values 转换为 ArrayList。

List<String> strs = (List<String>)(treemap.values());
return new ArrayList<String>(strs.subList(0, 5));

相同。尝试执行转换时出现运行时错误。好的,让我们分配给一个集合...

Collection<String> strs = treemap.values();
return new ArrayList<String>(strs.subList(0, 5));

对不起,subList不是 Collection 的方法。

Collection<String> strs = treemap.values();
ArrayList<String> a = new ArrayList<String>(strs);
return new ArrayList<String>(a.subList(0, 5));

终于有一些有用的东西了!但是两个额外的数据结构只是为了获得前五个元素?而且我不太喜欢使用 Double 作为 TreeMap 的键。

有没有更好的解决方案?

最佳答案

我不认为你会比上面的三行更紧凑,不是在 Java 中。

除此之外,我的印象是 Map 作为数据结构首先是错误的选择,因为您似乎不需要按字符串查找(除非您想要某种方式处理多次出现的字符串,但你没有这么说)。另一种方法是声明您自己的可比较数据记录类:

private static class Record implements Comparable<Record> {
// public final fields ok for this small example
public final String string;
public final double value;

public Record(String string, double value) {
this.string = string;
this.value = value;
}

@Override
public int compareTo(Record other) {
// define sorting according to double fields
return Double.compare(value, other.value);
}
}

// provide size to avoid reallocations
List<Record> records = new ArrayList<Record>(stringList.size());
for(String s : stringList)
records.add(new Record(s, calculateFitness(s));
Collections.sort(records); // sort according to compareTo method
int max = Math.min(10, records.size()); // maximum index
List<String> result = new ArrayList<String>(max);
for(int i = 0; i < max; i++)
result.add(records.get(i).string);
return result;

现在这比上面的三行要冗长得多(毕竟这是 Java),但也包括将键/值对插入映射所需的代码。

关于java - 按值排序的 Map<K, V> 的前 N ​​个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16296686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com