【问题标题】:How to sort a string list consists of digits and alphabets in Java?java - 如何对由Java中的数字和字母组成的字符串列表进行排序?
【发布时间】:2019-05-30 07:19:37
【问题描述】:

我有一个由数字和字母组成的项目列表,如下所示:

原名单:

Apple 1
Apple 1
Apple 4
Apple 1A
Apple 1B
Apple 1D
Apple 2A
Apple 2A
Apple 1C
Apple 1B
Apple 2C
Apple 10
Apple 11
Apple 5
Apple 11
Apple 8D
Banana 1
Banana 4
Banana 9D
Banana 9E
Banana 9C
Banana 13
Banana 16

它是来自 API 的搜索结果,但仅按 Apples 和 Bananas 的字母顺序排序。现在我想按数字排序(数字随机带有字母 A、B、C、D、E),如下所示:

带有A、B、C、D、E字母的数字应按数字和字母顺序排列。

预期列表:

Apple 1
Apple 1
Apple 1A
Apple 1B
Apple 1B
Apple 1C
Apple 1D
Apple 2
Apple 2A
Apple 2A
Apple 2C
Apple 4
Apple 5
Apple 8D
Apple 10
Apple 11
Banana 1
Banana 4
Banana 9C
Banana 9D
Banana 9E
Banana 13
Banana 16

我已经尝试过这个解决方案,但是它按项目以 0-9 数字开头,如下所示:

private List<Location> sortLocationList(List<Location> locationArrayList){
  Collections.sort(locationArrayList, new Comparator<Location>(){
    @Override
    public int compare(Location o1, Location o2){
      return o1.getValue().compareToIgnoreCase(o2.getValue());
    }
  });
  return locationArrayList;
}

public class Location{

  public enum LocationType{ADDRESS, STREET, CITY}

  private JavascriptObject object;
  private LocationType locationType;
  private String value;

  public Location(LocationType locationType, String value, JavascriptObject object){
    this.locationType = locationType;
    this.value = value;
    this.object = object;
  }
}

我的解决方案是返回这个:

Apple 1
Apple 1
Apple 10
Apple 11
Apple 1A
Apple 1B
Apple 1B
Apple 1C
Apple 1D
Apple 2
Apple 2A
Apple 2A
Apple 2C
Apple 4
Apple 5
Apple 8D
Banana 1
Banana 13
Banana 16
Banana 4
Banana 9C
Banana 9D
Banana 9E

对这个列表排序有更好的解决方案吗?

提前致谢。

【问题讨论】:

  • 将位置拆分为 Apple、2、C 等三个部分。如果它们不同,则按第一部分排序,如果相等,则按第二部分。如果第二个相等,则第三个
  • 谷歌“java字母数字比较”。你会发现许多问题和答案,以及许多算法——其中许多是错误的,有些是正确的。然后你的任务就是找到一个能正常工作的。

标签: java string algorithm sorting


【解决方案1】:

我假设总会有这样的模式:

"something something"

对于getValue() 方法返回的所有值
并且第二个"something" 将始终以带有或不带有尾随字符的数字开头。
下面的代码将每个这样的值分成 3 部分并比较
第一部分按字母顺序
第二部分数字和
3d 部分按字母顺序:

private List<Location> sortLocationList(List<Location> locationArrayList){
    Collections.sort(locationArrayList, new Comparator<Location>(){
        @Override
        public int compare(Location o1, Location o2){
            String s1 = o1.getValue();
            String s2 = o2.getValue();

            if (s1.equalsIgnoreCase(s2))
                return 0;

            String[] tokens1 = s1.split(" ");
            String[] tokens2 = s2.split(" ");

            if (!tokens1[0].equalsIgnoreCase(tokens2[0]))
                return s1.compareToIgnoreCase(s2);

            int number1 = Integer.parseInt(tokens1[1].replaceAll("\\D", ""));
            int number2 = Integer.parseInt(tokens2[1].replaceAll("\\D", ""));

            if (number1 != number2)
                return number1 - number2;

            String suffix1 = tokens1[1].replaceAll("\\d", "");
            String suffix2 = tokens2[1].replaceAll("\\d", "");

            return suffix1.compareToIgnoreCase(suffix2);
        }
    });

    return locationArrayList;
}

【讨论】:

  • 嗨@forpas,感谢您的关注和努力。您的解决方案完美解决了我的问题。
【解决方案2】:

按字母排序,字母在数字之后,“2”在“10”之后 您需要按名称、数字和后缀(可为空的字符串)排序,使用新类而不是字符串' 具有此属性(名称、编号和后缀)

// change String to a new type
private Product value;

并修复你的排序

@Override
   public int compare(Location o1, Location o2){
      int c;
      // compare name
      c = o1.getValue().getName().compareTo(o12.getValue().getName());
      if (c == 0) {
           // if is the same name compare number
           c = o1.getValue().getNum().compareTo(o2.getValue().getNum());
               if (c ==0 && o1.getValue().getSufix() != null) {
               // if is the same number compare suffix
               c = o1.getValue().getSufix().compareTo(o2.getValue().getSufix());
           }
      }
      return c;
   }

【讨论】:

  • 或者Collections.sort(locationArrayList, comparing(Location::getValue, comparing(Product::getName).thenComparing(Product::getNum).thenComparing(Product::getSuffix)));,但是让Product实现Comparable然后简单地Collections.sort(locationArrayList, comparing(Location::getValue))会更容易
  • 您好,感谢您的努力。您的解决方案看起来不错,但 @forpas 为我提供了完全适合我的问题的解决方案。
【解决方案3】:

正如@forpas 所说,将value 分成3 部分。

for example : "Apple 10AB"
Part1 - Apple (Alphabet)
Part2 - 10  (Digit)
Part3 - AB  (Alphabet)

Then 1. Compare Part1, if not equal do String Compare. If equals goto next step.
     2. Compare Part2(convert them to int), If not equal do int compare. If equals goto next step.
     3. Compare Part3, do String Compare.

排序代码如下

private List<Location> sortLocationList(List<Location> locationArrayList) {
    Collections.sort(locationArrayList, new Comparator<Location>() {
        @Override
        public int compare(Location o1, Location o2) {
            String[] objArr1 = o1.getValue().split(" ");
            String[] objArr2 = o2.getValue().split(" ");

            if(objArr1[0].equalsIgnoreCase(objArr2[0])) {//if Part1 is same

                //split digits and letters separately
                String[] digLetArr1 = objArr1[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
                String[] digLetArr2 = objArr2[1].split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
                Integer digit1 = Integer.parseInt(digLetArr1[0]);
                Integer digit2 = Integer.parseInt(digLetArr2[0]);

                //compare digit part (part2)
                if(digit1 == digit2) {

                    //Compare part3
                    if(digLetArr1.length == 1) {
                        return -1;
                    }
                    if(digLetArr2.length == 1) {
                        return 1;
                    }
                    return digLetArr1[1].compareTo(digLetArr2[1]);
                }
                else {
                    return digit1-digit2;
                }
            }
            else {
                return o1.getValue().compareToIgnoreCase(o2.getValue());
            }
        }
    });
    return locationArrayList;
}

【讨论】:

  • 嗨@NGV,感谢您的努力。您的解决方案看起来不错,但 forpas 为我提供了完全适合我的问题的解决方案。
猜你喜欢
  • 2021-02-21
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
相关资源
最近更新 更多