简体   繁体   English

Java:前缀字符串的棘手排序(ArrayLists)

[英]Java: Tricky sorting of prefixed Strings (ArrayLists)

(No networking knowledge required whatsoever. This is purely String and Lists). (无需任何网络知识。这纯粹是字符串和列表)。

Say I have a function in place, one that accepts a list of String IPv4 dotted address, and sorts them in ascending order. 假设我有一个函数,一个接受String IPv4点缀地址列表的函数,并按升序对它们进行排序。 (Not alphabetical, true ip long format sorting). (不是按字母顺序排列的,真正的ip长格式排序)。 Let's call this: 我们称之为:

public static ArrayList<String> sortListOfIpv4s(ArrayList<String> unsortedIPv4s);

This function already works correctly. 此功能已正常工作。 Given an input: 给出一个输入:

192.168.1.1, 8.8.8.8, 4.5.6.7, 244.244.244.244, 146.144.111.6

It will output the list: 它将输出列表:

4.5.6.7, 8.8.8.8, 146.144.111.6, 192.168.1.1, 244.244.244.244

(Let's not get into a debate on whether it should modify the list in place or return a new list. It just returns a new list. Also, the function cannot be modified because of numerous reasons. ) (让我们不讨论它是否应该修改列表或返回一个新列表。它只返回一个新列表。 此外,由于种种原因,该函数无法修改。


However, my input list looks like this: 但是,我的输入列表如下所示:

e192.168.1.1, f8.8.8.8, e4.5.6.7, f244.244.244.244, e146.144.111.6

When I remove the prefixes (only one of e or f, NOT NECESSARILY alternating) and create a clean array to pass to the sorting function, I lose the prefix information. 当我删除前缀(只有一个e或f,非NECESSARILY交替)并创建一个干净的数组传递给排序函数时,我丢失了前缀信息。 What I would like is an output of the type: 我想要的是类型的输出:

e4.5.6.7, f8.8.8.8, e146.144.111.6, e192.168.1.1, f244.244.244.244

Basically, prior to sorting, whatever prefix was present for each element in the unsorted list, the same prefix needs to be added back to the elements in the sorted list. 基本上,在排序之前,对于未排序列表中的每个元素存在任何前缀,需要将相同的前缀添加回排序列表中的元素。

Caveats: 注意事项:

  • An IP Address can repeat in the original list, a maximum of two times IP地址可以在原始列表中重复,最多两次
  • When repeating twice, each of the two elements will have the same prefix, guaranteed 重复两次时,两个元素中的每一个都将具有相同的前缀,保证
  • Sorting algorithm will not remove duplicates. 排序算法不会删除重复项。

A little algorithmic help please? 有点算法帮助吗? (Remember, we already have a function that can sort clean IPv4 String arraylists). (请记住,我们已经有一个可以对干净的IPv4 String arraylists进行排序的函数)。

Don't remove the prefixes prior to passing it to the sorting function. 在将前缀传递给排序函数之前,请不要删除前缀。 Instead, in the sortListOfIpv4s method, always compare Strings using s.substring(1) , which will give you the entire string without the prefix, and add s to the resulting sorted array. 相反,在sortListOfIpv4s方法中,始终使用s.substring(1)比较字符串,它将为您提供不带前缀的整个字符串,并将s添加到生成的排序数组中。

If sortListOfIpv4s is a black box and you are required to pass the prefix-free Strings, then you could cache the prefixes beforehand in a Map from prefix-free IP -> prefix : 如果sortListOfIpv4s是一个黑盒子,并且你需要传递无前缀的字符串,那么你可以事先将前缀缓存在一个Mapprefix-free IP -> prefix

Map<String, String> prefixMap = new HashMap<String, String>();
for (String ip : unsortedIPv4s) {
  prefixMap.put(ip.substring(1), ip.substring(0, 1));
}

Then sort and recover the prefixes from the Map : 然后从Map排序并恢复前缀:

List<String> sortedIPV4s = sortListOfIpv4s(unsortedIPv4s);
for (String ip : sortedIPV4s) {
  String prefix = prefixMap.get(ip);
  String originalIp = prefix + ip;
}

您的方法可以将任何前缀移动到String的末尾,对列表进行排序,然后再次遍历字符串并将前缀从末尾移回到开头。

You could implement Comparator: 你可以实现比较器:

public class IpComparator implements Comparator<String> {
    @Override
    public int compare(String ipA, String ipB) {
        return doComparison( ipA.substring(1), ipB.substring(1) );
    }
}

Then you can use it: 然后你可以使用它:

return Collections.sort(unsortedIPv4s, new IpComparator());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM