【问题标题】:Sort an array of strings by a part of the string or index?按字符串或索引的一部分对字符串数组进行排序?
【发布时间】:2016-10-17 05:17:48
【问题描述】:

我已经编写了这个程序,我让它按字母顺序对字符串数组进行排序。我希望能够按字符串的不同部分对它进行数字排序。 (我也在使用eclipse)。 这是我所拥有的:

import edu.princeton.cs.algs4.Merge;

public class sortNum {

    public static void main(String[] args) {
    // TODO Auto-generated method

    String[] age = {"Meredith Chicago #82", 
            "Brian Phoenix #45", "Jess Miami #26", 
            "Gunther NYC #53", "Frank Boise #4"};

    System.out.println("-----------------------------");

    //loop through array and print out unsorted string

    for(String i : age){
        System.out.printf("%25s\n", i); //to right-align

    }

    System.out.println("-----------------------------");

    Merge.sort(age);

    //loop through array and print sorted string

    for(String j: age){
        System.out.println(j); //this is where I am unsure of the right way
    }



    System.out.println("-----------------------------");
  }

}

对于输出,我得到这个:

-----------------------------
     Meredith Chicago #82
        Brian Phoenix #45
           Jess Miami #26
          Gunther NYC #53
           Frank Boise #4
-----------------------------
Brian Phoenix #45
Frank Boise #4
Gunther NYC #53
Jess Miami #26
Meredith Chicago #82
-----------------------------

显然这是因为它查看了字符串的开头。这不是问题,当然也是意料之中的。

我可以将其设置为查看数字的位置吗?可以通过计算索引来完成吗?例如,从末尾 (-1) 索引开始计数但不包括 # 并按此排序?当然是升序。我仍在寻找使用 for 循环。

我本来打算在没有循环的情况下为每条信息创建单独的对象,但后来意识到这将花费很长时间并且代码太多。

【问题讨论】:

  • 什么是Merge?它在哪里定义?如果您使用 Java 库排序方法,您可以提供自定义的 Comparator 实现以您喜欢的任何方式进行排序,但我们不知道您使用的类是否可以这样做。
  • 是的,您可以按字符串的数字部分对数组进行排序。只需正确拆分字符串,提取数字,将其转换为 int 并进行排序。可能还有其他方法可以做到这一点。它回答了你的问题吗?或者您希望有人通过提供一段代码来向您展示如何做到这一点?
  • @JimGarrison 我正在使用来自algs4.cs.princeton.edu/code 的algs4.jar,其中包括Merge。另外,这里是merge algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/… 的定义。通过阅读,我认为这是可能的。我只是不确定如何实现它,因为我是 Java 新手。
  • @Nurzhan 确实如此,我相信它可以做到,因为我相信这是一个相当简单的概念,但是,如果你能提供一些解释这一点的代码,那将会很有帮助。我想要一些关于实施和应用的指导。

标签: java arrays eclipse sorting mergesort


【解决方案1】:

我建议您为此类数据创建单独的对象,如下所示:

public class User implements Comparable<User> {
  private int mId;
  private String mName;

  public User(final int id, final String name) {
    mId = id;
    mString = name;
  }

  public String getName() {
    return mName;
  }

  @Override
  public int compare(final User lhs, final User rhs) {
    return Integer.compare(lhs.mId, rhs.mId);
  }

  @Override
  public String toString() {
    return String.format("%s #%d", mName, mId);
  }
}

我在这里实现了Comparable&lt;User&gt;,您可以根据需要覆盖比较类型。这里我只是比较用户的 id。 在此之后,您可以根据需要使用Collections.sort(List&lt;User&gt;)Merge.sort(Comparable[]),它们将被排序。此外,重写 toString() 方法可以将用户信息简单地输出为 user.toString()

【讨论】:

  • ((Integer) lhs.mId).compareTo(rhs.mId) 应该是 Integer.compare(lhs.mId, rhs.mId)。不要自动装箱整数只是为了比较它们。
  • @Andreas 感谢您的建议!我现在将编辑答案。我展示了这种方式,因为我是 Android 程序员,我们没有原生 Integer.compare(int, int) :)
【解决方案2】:

您可以使用Arrays.sort 对数组进行排序并为其提供自定义比较器。例如,使用 Java 8:

Arrays.sort(age, Comparator.comparingInt(a -> Integer.parseInt(a.split("#")[1])));

虽然此代码有效,但我建议创建一个类来封装逻辑。

public class Person {
    public static Person decode(String line) {
        Matcher matcher = Pattern.compile("(\\w+) #(\\d+)").matcher(line);
        if (!matcher.matches())
            throw new IllegalArgumentException("Illegal format");
        return new Person(matcher.group(1), matcher.group(2));
    }

    public int getAge() {...}
    public String getName() {...}
}

然后使用流,您的代码可以变得更加明确:

Arrays.stream(age)
    .map(Person::decode)
    .sorted(Comparator.comparingInt(Person::getAge))
    .forEach(...);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2012-10-14
    • 2014-10-28
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多