对String中的可能数字进行排序

时间:2014-07-09 12:54:07

标签: java string sorting

我有以下可能的地址作为字符串(未排序):

"road 21"
"road 1"
"road 186"
"road +21 / 23"
"road +21 / 19"
"another road 21"
"another road 1"

我希望能够将它们排序为(所以不是默认的String排序方式):

another road 1
another road 21
road 1
road 21
road +21 / 19
road +21 / 23
road 186

我该怎么做?我可能不得不使用自定义比较器,但是我应该如何拆分String?

5 个答案:

答案 0 :(得分:3)

我用Java实现了这个,我知道它起初看起来很奇怪。

如果您有任何问题请随时问我

public class SpecialComparator implements Comparator<String> {

   @Override
    public int compare(String arg0, String arg1) {
     // TODO Auto-generated method stub
     String []words1=arg0.split(" ");
     String [] words2 = arg1.split(" ");
     int i = 0;

        if (words1[i].hashCode()>words2[i].hashCode()){
            return 1;
        }
        else if (words1[i].hashCode()<words2[i].hashCode()){
            return -1;
        }
        else if (words1[i].hashCode()==words2[i].hashCode())
            return compare(arg0.substring(i+1, arg0.length()), arg1.substring(i+1,arg1.length()));
        else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words1.length){
            return -1;
        }
        else if (i == Math.min(words1.length,words2.length)-1 && Math.min(words1.length,words2.length) == words2.length){
            return 1;
        }
        else if (i == Math.min(words1.length,words2.length)-1 && words1.length == words2.length){
            return 0;
        }
        else{
            return 0;
        }


   }


   public static void main (String[] args){
    ArrayList<String> input = new ArrayList<String>();
    SpecialComparator a = new SpecialComparator();
    input.add("road 21");
    input.add("road 1");
    input.add("road 186");
    input.add("road +21 / 23");
    input.add("road +21 / 19");
    input.add("another road 21");
    input.add("another road 1");
    Collections.sort(input,a);
    for (String ans : input){
        System.out.println(ans);
    }

  }



 }

答案 1 :(得分:1)

您的格式似乎是:

  • {名称}
  • {数}
  • 可选的斜杠字符
  • 可选第二个{number}。

因此,我会使用这些属性创建一个表示此格式的对象:

public class MyInput {
  private String name;
  private Integer firstNumber;
  private Integer secondNumber;
}

然后解析输入文件以创建List<MyInput>

最后,您创建自定义Comparator可以调用Collections.sort(yourList, yourCustomComparator)

答案 2 :(得分:0)

这个问题似乎很多。我一直在使用Martin Pools NaturalOrderCompartor。您可以轻松地将其移植到您的代码中。

https://github.com/paour/natorder/blob/master/NaturalOrderComparator.java

答案 3 :(得分:0)

它有点讨厌,但这是我解决你问题的方法

List<String> list = Arrays.asList("road 21", "road 1", "road 186",
                "road +21 / 23", "road +21 / 19", "another road 21",
                "another road 1");

        Collections.sort(list, new Comparator<String>() {

            Integer toNumber(String string) {
                try {
                    return Integer.parseInt(string);
                } catch (NumberFormatException e) {
                    return null;
                }
            }

            @Override
            public int compare(String o1, String o2) {
                String[] left = o1.split("\\s+");
                String[] right = o2.split("\\s+");
                for (int i = 0; i < Math.min(left.length, right.length); i++) {
                    String ls = left[i];
                    String rs = right[i];

                    Integer li = toNumber(ls);
                    Integer ri = toNumber(rs);

                    if (li != null && ri != null
                            && li.intValue() != ri.intValue()) {
                        return li.intValue() - ri.intValue();
                    } else if (li != null && ri == null) {
                        return 1;
                    } else if (li == null && ri != null) {
                        return -1;
                    } else if (li == null && ri == null){
                        int compared = ls.compareToIgnoreCase(rs);
                        if (compared != 0) {
                            return compared;
                        }
                    }

                }
                return left.length - right.length;
            }
        });

但是如果您可以改变您的结构,那么请使用Arnaud Denoyelle提出的解决方案

答案 4 :(得分:0)

您也可以尝试使用比较器:

class MyComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        o1 = o1.replace("+", "");
        o2 = o2.replace("+", "");

        String[] a1 = o1.split(" ");
        String[] a2 = o2.split(" ");
        int length = (a1.length > a2.length) ? a2.length : a1.length;

        for (int i = 0; i < length; i++) {
            if (!a1[i].equalsIgnoreCase(a2[i])) {
                if (!isIntegerRegex(a1[i]) || !isIntegerRegex(a2[i])) {
                    return o1.compareTo(o2);
                }
                int f = Integer.parseInt(a1[i]);
                int s = Integer.parseInt(a2[i]);
                return f - s;
            }
        }

        return a1.length - a2.length;
    }

    public boolean isIntegerRegex(String str) {
        return str.matches("^[0-9]+$");
    }
}

并称之为:

public String[] sortStrings(String[] input) {
    Arrays.sort(input, new MyComparator());
    return input;
}