gpt4 book ai didi

Java - 字符串的自定义排序ArrayList

转载 作者:行者123 更新时间:2023-12-01 11:21:06 25 4
gpt4 key购买 nike

我想按特定顺序对长度为 1 或 2 的字符串组成的 ArrayList 进行排序。

顺序是

1m, 2m, 3m ... 9,, 1p...9p, 1s...9s, E, S, W, N,Wd, Gd, Rd

你明白了吗?

例如,ArrayList是;

N 2p 9s 9s 1p 9m N 4s 1m 5p 7m 2s 5s 5m  

我正在尝试在类中编写一个方法,其中 ArrayList 是一个字段,它将按照所需的顺序放置它。

问题与比较器相似,但我发现每个解释都非常令人困惑,但无论如何,做的事情与我想要的不同。

只要完整地写下订单就可以了。

最佳答案

既然我主张重新打开这个,这里有一个 Comparator<String>这将做你想做的事:

package testJ;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class WeirdOrderComparator implements Comparator<String> {
private static List<String> COMPASS_ORDER = Arrays.asList("E:S:W:N"
.split(":"));
private static List<String> D_ORDER = Arrays.asList("W:G:R".split(":"));
private static List<String> SUFFIX_ORDER = Arrays.asList("m:p:s::d"
.split(":"));

private int indexFor(String target, List<String> order) {
int r = order.indexOf(target);
if (r < 0) {
return order.size();
} else {
return r;
}
}

private int getSuffixNumber(String s) {
switch (s.length()) {
case 1:
return indexFor("", SUFFIX_ORDER);
case 2:
return indexFor(s.substring(1), SUFFIX_ORDER);
default:
return 99;
}
}

private int getWithinGroupNumber(int suffixGroup, String s) {
switch (suffixGroup) {
case 0:
case 1:
case 2:
return Integer.valueOf(s.substring(0, s.length() - 1));
case 3:
return indexFor(s, COMPASS_ORDER);
case 4:
return indexFor(s.substring(0, 1), D_ORDER);
default:
return 99;
}
}

public int compare(String o1, String o2) {
int sfx1 = getSuffixNumber(o1);
int sfx2 = getSuffixNumber(o2);
if (sfx1 != sfx2) {
return sfx1 - sfx2;
}
int grp1 = getWithinGroupNumber(sfx1, o1);
int grp2 = getWithinGroupNumber(sfx2, o2);
if (grp1 != grp2) {
return grp1 - grp2;
}
return o1.compareTo(o2);
}
}

它可以用作:

package testJ;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class WeirdOrderTest {
public static void main(String args[]) {
List<String> testList = Arrays.asList("N 2p 9s 9s 1p 9m N 4s 1m 5p 7m 2s 5s 5m".split(" "));
System.out.println("Original order: " + testList);
ArrayList<String> sorted = new ArrayList<String>();
sorted.addAll(testList);
Collections.sort(sorted, new WeirdOrderComparator());
System.out.println("Sorted: " + sorted);
}
}

这会产生:

Original order: [N, 2p, 9s, 9s, 1p, 9m, N, 4s, 1m, 5p, 7m, 2s, 5s, 5m]
Sorted: [1m, 5m, 7m, 9m, 1p, 2p, 5p, 2s, 4s, 5s, 9s, 9s, N, N]

这里的总体策略是:

  1. 找到可以区分两个字符串的规则。在这种情况下,我首先确定字符串的一般“组”:以“m”、“p”、“s”结尾、单个字母或以“d”结尾的内容。

  2. 如果该规则区分两个输入,则返回一个负数,如果 o1应该排在第一位,如果 o1 则为正应该稍后来。要记住这个约定,请思考“如果 o1 - o2o1 是小整数,则就像 o2”(忽略溢出)。

  3. 如果该规则不能区分 o1o2 ,找到另一个规则等等。

  4. 最后,如果您用完了规则,则返回 0 或委托(delegate)给其他比较。

请记住,您的 Comparator应该合理地处理您不期望的字符串 - 它可能会抛出异常(如果您给它“Xs”,则会抛出异常),但如果它不抛出异常,那么结果应该是一致的。也就是说,如果compare(x, y) < 0compare(y, z) < 0那么如果compare(x, z)不抛出异常,compare(x, z)必须为负,无论什么 x , y ,和z是。确保这一点的一种方法是按照我在这里所做的方式构建比较器,我为每个字符串找到一系列“顺序号”,然后委托(delegate)给 String.compareTo如果订单号没有帮助。

关于Java - 字符串的自定义排序ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31221791/

25 4 0