【问题标题】:Java- Sort String with multiple decimal pointsJava-对具有多个小数点的字符串进行排序
【发布时间】:2016-06-21 04:11:58
【问题描述】:

我有一个Hashmap<String,Integer>,密钥是一个唯一的字符串,格式如下:

"abc1.0","bcd1.1","xyz2.1.1","cdef1.2.1"...

现在我需要使用该键对这个哈希图进行排序,但按数字顺序排序,小数点按以下顺序排列:

"abc1.0","bcd1.1","cdef1.2.1","xyz2.1.1",...

我正在尝试使用 A 树图的比较器,但没有正确排序。

例如:

Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String key1, String key2) {
        .....
        //Counted decimal points and if > 2
        k1 = Integer.parseInt(key1.substring(1).split("\\.")[countOfDecimals]);
         //same for key2 
         ......
      } 
      return Double.compare(k1, k2);
}

编辑:

  • 小数点为 '4' 时的最大个数
  • 应按数值排序,文字请忽略

几乎尝试了所有给出的例子是 STO 但没有成功:( 如果涉及两个或多个小数点,则不排序。请帮忙!!

【问题讨论】:

  • 如果有多个,我认为它们不是小数点...
  • 您的示例令人困惑,因为不清楚您是按字母顺序排序还是仅按数字后缀排序。
  • “小数”的数量或它们之间的值是否有限制?
  • 为什么你使用Map&lt;String, Integer&gt; 而这些stings 显然不是整数(例如1.2.3.4 不是整数,它是一个由四个整数组成的字符串)。映射存储唯一键,并忽略重复项,因此您不能将相同的键映射 - 例如 xyz2.1.1.4 到许多整数 (2,1,1,4)。你能解释一下吗,因为我不清楚你想用这个 MAP 实现什么?为什么不使用简单的 List 或 Array 并对其进行排序?

标签: java sorting hashmap comparator


【解决方案1】:

尝试使用正则表达式提取所有十进制数并对其进行排序:

Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return Double.compare(Double.valueOf(a.replaceAll("[^\\d+(?:\\.\\d+)?]","")), 
                    Double.valueOf(b.replaceAll("[^\\d+(?:\\.\\d+)?]","")));
        }
    });
    mp.put("abd10.9",6);
    mp.put("abd17.02",65);
    mp.put("nmbd1.02",17);
    mp.put("klbd7.028",10);
    mp.put("klbd7.023",9);

//升序

{nmbd1.020=17, klbd7.023=9, klbd7.028=10, abd10.9=6, abd17.02=65}

//以下评论中讨论的更改: //这只能在小数长度相同时起作用,如果不是,则应添加零以填充剩余空间以使排序正常工作

 Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return Integer.compare(Integer.valueOf(a.replaceAll("\\D+","")),
                    Integer.valueOf(b.replaceAll("\\D+","")));
        }
    });
    mp.put("abd10.9.0.9",6);
    mp.put("gbd17.0.6.2",65);
    mp.put("nmbd2.0.9.2",17);
    mp.put("klbd7.0.2.7",10);
    mp.put("rlbd8.1.2.8",10);
    mp.put("opbd9.0.2.3",9);
    mp.put("mpbd7.0.3.2",9);
    mp.put("wpbd7.0.7.0",9);

输出:

{nmbd2.0.9.2=17, klbd7.0.2.7=10, mpbd7.0.3.2=9, wpbd7.0.7.0=9, rlbd8.1.2.8=10, opbd9.0.2.3= 9、abd10.9.0.9=6,gbd17.0.6.2=65}

【讨论】:

  • 这依赖于单个数字。
  • @shmosel 它提取“。”之前和之后的数字。在这种情况下,它不限制小数的长度,因此它可以捕获所有内容,就像这样,“[^\\d+\\.\\d+]” 一个简单的概念来捕获小数
  • 但是您的排序会将 10.0 放在 1.10 之前。
  • 10.0 小于 1.10。
  • @SeekAddo 感谢您的时间兄弟.. 它工作得很好。
【解决方案2】:

尝试从键中的字符串中提取数字并对其进行树排序。当你最终得到一个像“1.0”、“1.1”、“2.1.1”、“1.2.1”这样的列表时......

然后你对它们进行排序,它会返回你期望的顺序:

“1.0”、“1.1”、“1.2.1”、“2.1.1”

【讨论】:

  • 这依赖于单个数字。
【解决方案3】:

您需要对字符串进行标记 - 将其拆分为:

  • 文字
  • 版本(1.2.3)
  • 颠覆 (1.2.3)
  • subsubversion (1.2.3)

然后使用字符串比较器比较文本,并遍历所有版本/子版本并使用整数比较进行比较。

【讨论】:

    【解决方案4】:

    您可以做的是提取要比较的键中字符串的数字部分:

    例如,如果键是“abc1.5.02”和“zxy1.4.3”,那么数字部分是“1.5.02”和“1.4.3”

    接下来,填充这些数字字符串的组成部分,使它们在每个 subversion 中都有 2 个数字。

    也就是说,

    "1.5.02" --> "1.50.02.00.00" (add "00"s since you can have up to 4 decimal points)
    "1.4.3"  --> "1.40.30.00.00"
    

    接下来,将这两个都转换为长整数。

    "1.50.02.00.00" --> 150,020,000 (call this val1)
    "1.40.30.00.00" --> 140,300,000 (call this val2)
    

    最后,返回Long.compare(val1, val2)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 1970-01-01
      相关资源
      最近更新 更多