【问题标题】:Sort strings that contains number对包含数字的字符串进行排序
【发布时间】:2017-05-19 14:52:15
【问题描述】:

我有一个包含数字的字符串列表:

例子:

String 1.0.2
String 2.1.2
String 10.0.1
String 3.0.1
String 2.3.1
String 10.2.1

我需要对这个列表进行排序并得到这个:

String 1.0.2
String 2.1.2
String 2.3.1
String 3.0.1
String 10.0.1
String 10.2.1

但是如果我使用 java 函数 Collections.sort 我得到这个:

String 1.0.2
String 10.0.1
String 10.2.1
String 2.1.2
String 2.3.1
String 3.0.1

编辑:

我试过这个比较器:

public int compare(String o1, String o2) {
    int a = Integer.parseInt(o1.split(" ")[1].replace(".", ""));
    int b = Integer.parseInt(o2.split(" ")[1].replace(".", ""));

    return a-b;
}

当我运行应用程序时,我收到此错误java.lang.NumberFormatException: For input string: "Unknown" 我如何检查是否有不包含数字的字符串以便我可以测试这个比较器?

【问题讨论】:

标签: java


【解决方案1】:

您可以获取这些字符串的数值并使用 java8 流

List<String> myList = Arrays.asList("String 1.0.2", "String 2.1.2", "String 10.0.1", "String 3.0.1",
            "String 2.3.1", "String 10.2.1");

myList.sort((x, y) -> Integer.compare(Integer.parseInt(x.replace(".", "").split(" ")[1]),
            Integer.parseInt(y.replace(".", "").split(" ")[1])));
System.out.println(myList);

【讨论】:

    【解决方案2】:

    您可以编写如下比较器:

    @Override
    public int compare(String o1, String o2) {
        int a = Integer.parseInt(o1.split(" ")[1].replace(".", ""));
        int b = Integer.parseInt(o2.split(" ")[1].replace(".", ""));
        return a - b;
    }
    

    然后就是:

    CustomComparator comp = new CustomComparator();
    Collections.sort(list, comp);
    

    希望对你有帮助!

    【讨论】:

    • 此解决方案不适用于“10.1.1”和 1.100.1
    • 我试图实现这个比较器,但我得到一个错误。我已经更新了我的问题,所以你可以看到错误是什么
    【解决方案3】:

    相反,您可以使用这样的比较器:

    List<String> list = Arrays.asList("1.0.2", "2.1.2", "10.0.1", "3.0.1", "2.3.1", "10.2.1");
    System.out.println(list);
    Collections.sort(list, (o1, o2) -> {
        return Integer.parseInt(o1.replace(".", "")) - Integer.parseInt(o2.replace(".", ""));
    });
    System.out.println(list);
    

    输出

    [1.0.2, 2.1.2, 10.0.1, 3.0.1, 2.3.1, 10.2.1]
    [1.0.2, 2.1.2, 2.3.1, 3.0.1, 10.0.1, 10.2.1]
    

    想法是:

    1. 将所有. 替换为空
    2. 将您的号码转换为正确的号码
    3. 像任何数字一样比较结果。

    【讨论】:

    • 我尝试按照您的想法制作比较器,但出现错误。我已经更新了我的问题,所以你可以看到错误是什么。你知道我该如何解决这个问题
    • @alonso05 这不是我的解决方案,我认为您尝试了另一个解决方案 :)
    【解决方案4】:

    您需要对它们进行标记,然后从最重要的标记到末尾进行比较。 举个例子,你可以做如下比较两个序列a和b。

        public int compare(Sring a,String b){
            String[] aToken = a.slpit(".");
            String[] bToken = b.slpit(".");
            if (aToken.length > bToken.length){
                return 1;
             }
            if (bToken.length > aToken.length){
                return -1;
            }
            for (int i=0; i<bToken.length; i++){
                if (aToken[i].compareTo(b[i]Token) != 0){
                   return aToken[i].compareTo(bToken[i]);
               }
           }
          return 0;
        }
    

    从这个 sn-p 你可以构建你的比较器 希望对您有所帮助

    【讨论】:

      【解决方案5】:

      我已经用这个比较器解决了我的问题:

      public int compare(String o1, String o2)
              {
                  String a = o1.toString();
                  String b = o2.toString();
      
                  int ia = 0, ib = 0;
                  int nza = 0, nzb = 0;
                  char ca, cb;
      
                  while (true) {
                      // Only count the number of zeroes leading the last number compared
                      nza = nzb = 0;
      
                      ca = charAt(a, ia);
                      cb = charAt(b, ib);
      
                      // skip over leading spaces or zeros
                      while (Character.isSpaceChar(ca) || ca == '0') {
                          if (ca == '0') {
                              nza++;
                          } else {
                              // Only count consecutive zeroes
                              nza = 0;
                          }
      
                          ca = charAt(a, ++ia);
                      }
      
                      while (Character.isSpaceChar(cb) || cb == '0') {
                          if (cb == '0') {
                              nzb++;
                          } else {
                              // Only count consecutive zeroes
                              nzb = 0;
                          }
      
                          cb = charAt(b, ++ib);
                      }
      
                      // Process run of digits
                      if (Character.isDigit(ca) && Character.isDigit(cb)) {
                          int bias = compareRight(a.substring(ia), b.substring(ib));
                          if (bias != 0) {
                              return bias;
                          }
                      }
      
                      if (ca == 0 && cb == 0) {
                          // The strings compare the same. Perhaps the caller
                          // will want to call strcmp to break the tie.
                          return nza - nzb;
                      }
                      if (ca < cb) {
                          return -1;
                      }
                      if (ca > cb) {
                          return +1;
                      }
      
                      ++ia;
                      ++ib;
                  }
              }
      
              int compareRight(String a, String b)
              {
                  int bias = 0, ia = 0, ib = 0;
      
                  // The longest run of digits wins. That aside, the greatest
                  // value wins, but we can't know that it will until we've scanned
                  // both numbers to know that they have the same magnitude, so we
                  // remember it in BIAS.
                  for (;; ia++, ib++)
                  {
                      char ca = charAt(a, ia);
                      char cb = charAt(b, ib);
      
                      if (!Character.isDigit(ca) && !Character.isDigit(cb)) {
                          return bias;
                      }
                      if (!Character.isDigit(ca)) {
                          return -1;
                      }
                      if (!Character.isDigit(cb)) {
                          return +1;
                      }
                      if (ca == 0 && cb == 0) {
                          return bias;
                      }
      
                      if (bias == 0) {
                          if (ca < cb) {
                              bias = -1;
                          } else if (ca > cb) {
                              bias = +1;
                          }
                      }
                  }
              }
      
              static char charAt(String s, int i) {
                  return i >= s.length() ? 0 : s.charAt(i);
              }
      

      【讨论】:

        猜你喜欢
        • 2020-02-18
        • 2016-10-28
        • 1970-01-01
        • 2021-08-12
        • 2019-05-26
        • 2011-03-07
        • 1970-01-01
        • 2014-05-05
        相关资源
        最近更新 更多