无法对以下树图进行排序

发布于 2024-10-26 22:25:30 字数 716 浏览 6 评论 0原文

for (a = 0; a < filename; a++) {
  Map<Double,String> m = new HashMap<Double,String>();

  String pre = "abc";
  String post = ".txt";
  for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
  }
  SortedSet<Double> set = new TreeSet<Double>(m.keySet());
  for (Double d : set) {
    System.out.println(d + " " + m.get(d));
  }
}

输出:

0.5773502691896258 abc0.txt
0.5773502691896258 abc1.txt
0.5773502691896258 abc2.txt
NaN abc3.txt
0.5773502691896258 abc4.txt
NaN abc5.txt
NaN abc6.txt
NaN abc7.txt
NaN abc8.txt
0.5773502691896258 abc9.txt
NaN abc10.txt

此代码应该能够对双精度值进行排序。但它在顶部显示输出。发生什么事 ?

for (a = 0; a < filename; a++) {
  Map<Double,String> m = new HashMap<Double,String>();

  String pre = "abc";
  String post = ".txt";
  for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
  }
  SortedSet<Double> set = new TreeSet<Double>(m.keySet());
  for (Double d : set) {
    System.out.println(d + " " + m.get(d));
  }
}

Output :

0.5773502691896258 abc0.txt
0.5773502691896258 abc1.txt
0.5773502691896258 abc2.txt
NaN abc3.txt
0.5773502691896258 abc4.txt
NaN abc5.txt
NaN abc6.txt
NaN abc7.txt
NaN abc8.txt
0.5773502691896258 abc9.txt
NaN abc10.txt

This code should be able to sort the double values. But it displays the output on top. What happen ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

微凉 2024-11-02 22:25:30

几乎可以肯定问题是NaN

顾名思义,这不是一个真正的数字,并且在比较方面表现得非常奇怪。 NaN 是大于、等于还是小于 0.5773502691896258?它可以是这些结果中的任何一个,甚至不需要在程序的单次执行中保持一致。 NaN 甚至不等于它本身,这说明了当涉及 NaN 时,平等法则和强顺序的先入之见如何消失。

因此,解决方法是不要使用非数字并期望 Double.compareTo() 来执行您想要的操作。根据从 similarityScore() 返回时 NaN 的含义,您可以采取多种方法。如果这意味着根本不匹配,您可以让该方法返回 Double (而不是 double),在中返回 null这些情况下,然后只将非空结果添加到地图中。如果无论如何都应该显示这些结果,那么您也许可以使用 0.0-1.0 的结果,假设该结果小于任何“真实”相似度得分。如果您想要更精致的东西,那么返回像原始双精度一样纯粹和直接的东西可能会成为问题,并且您可能需要返回您自己的(简单)域类。


顺便说一句 - 为什么要创建并填充 HashMap,然后使用 TreeSet 来获取键的迭代顺序?如果您只是将 m 创建为 TreeMap;您得到的正是您想要的迭代顺序,因此只需迭代m.entrySet()`即可。它更清晰、更惯用(因此更容易理解)并且更高效,所以没有理由不这样做。

The problem is almost certainly NaN.

This is, as the name suggests, not a realy number, and behaves very strangely in terms of comparisons. Is NaN greater than, equal to, or less than 0.5773502691896258? It could be any of those results, and isn't even required to be consistent within a single execution of the program. NaN is not even equal to itself, which says something about how preconceptions of the laws of equality, and strong ordering, go out of the window when NaN is involved.

So the fix is not to use a non-numeric and expect Double.compareTo() to do what you want with it. Depending on what NaN means when returned from similarityScore(), there are several approaches you could take. If it means that it's not a match at all, you could have that method return a Double (rather than a double), return null in these cases, and then only add non-null results to the map. If these results should be displayed anyway, then perhaps you could use a result of 0.0 or -1.0, assuming that's less than any "real" similarity score. If you want something more finessed, then returning something as pure and straightforward as a primitive double is likely going to be the problem, and you may need to return your own (simple) domain class instead.


As an aside - why on earth do you create and populate a HashMap, then use a TreeSet to get the iteration order over the keys? If you simply create m as a TreeMap<Double, String> you get exactly the iteration order you want, so can just iterate overm.entrySet()`. It's clearer, more idiomatic (thus more understandable), and more efficient, so there's no reason not to do this.

空名 2024-11-02 22:25:30
for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
}

这会将相同的值放入映射 11 次 - 您没有在循环内引用 ii 。

for (Double d : set) {
    System.out.println(d + " " + m.get(d));
}

这将打印地图中的单个条目。

您对值 0..filename 执行上述操作 - 多次向地图添加值,然后打印它并使用新地图重新启动。

Map<Double,String> m = new HashMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
SortedSet<Double> set = new TreeSet<Double>(m.keySet());
for (Double d : set) {
  System.out.println(d + " " + m.get(d));
}

这将创建一个地图,用 0..filename 的值填充它,然后按排序打印它。您仍然会遇到无法真正排序的 NaN 问题。

Map<Double,String> m = new TreeMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
for (Double d : m.keySet()) {
  System.out.println(d + " " + m.get(d));
}

这使用了 TreeMap - 不需要中间 Set

for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
}

This puts the same value into the map 11 times - you're not referencing ii inside the loop.

for (Double d : set) {
    System.out.println(d + " " + m.get(d));
}

This prints the single entry in the map.

You do the above for values 0..filename - Adding a value to the map several times, then printing it and restarting with a new map.

Map<Double,String> m = new HashMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
SortedSet<Double> set = new TreeSet<Double>(m.keySet());
for (Double d : set) {
  System.out.println(d + " " + m.get(d));
}

This creates a map, populates it with values for 0..filename, then prints it sorted. You'll still have issues with NaN which isn't really sortable.

Map<Double,String> m = new TreeMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
for (Double d : m.keySet()) {
  System.out.println(d + " " + m.get(d));
}

And this uses a TreeMap - No need for the intermediate Set

梦忆晨望 2024-11-02 22:25:30

对于任何要排序的集合,要排序的值的类型应该相同。并且应该实现类似的接口。

在您的情况下,您需要对 NaN 和 Double 值进行排序。

For any Collection to sort, the type of the value on which you are sorting should be same. And should implement comparable interface.

In your case you have NaN and Double values to sort.

¢蛋碎的人ぎ生 2024-11-02 22:25:30

您的循环意味着您要分别对每个文件名进行排序。您需要将排序从循环中拉出来才能对这些值进行排序。 (哎呀,@Eric 比我先一步。)

Your loop means you're sorting for each filename separately. You'll need to pull the sorting out of the loop to get those values sorted. (Ooops, @Eric beat me to it.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文