美文网首页
探究Java自然排序算法

探究Java自然排序算法

作者: Uncle阳 | 来源:发表于2017-04-25 23:30 被阅读161次
natSort

说明

现实生活中有很多场景需要用到“自然排序”的算法,比如对金钱表示的排序:“¥165.2,¥-365.03,¥+0.80”,还比如对日志文件名称排序“version1.0.log,version1.1.log1,version01.1.log2”等。这种情况下使用常规的字符串排序得到的结果是与实际业务不符合的,即使查阅了一些第三方的开源框架,也没有找到很好解决这个问题的方式(主要是业务性比较强),所以不得已自己花了些时间写了一个满足“自然排序”算法。

代码

/**
 * <自然排序算法>
 * <详细介绍>
 *
 * @author Uncle阳zzZ
 * @since 设计wiki | 需求wiki
 */
public class NatSortComparator implements Comparator<Object> {

    private boolean careCase = false;

    private Pattern patternA;
    private Pattern patternB;


    /**
     * careCase
     * @param careCase
     */
    public NatSortComparator(boolean careCase)  {
        this.careCase = careCase;

        String pattern = "(-|\\+)?\\d+(.\\d+)?"; //^
        patternA = Pattern.compile(pattern);
        patternB = Pattern.compile(pattern);
    }

    /**
     * 比较算法
     * @param a
     * @param b
     * @return
     */
    @Override
    public int compare(Object a, Object b) {

        // simple compare
        if (a == b) {
            return 0;
        }

        if (a == null) {
            return -1;
        }

        if (b == null) {
            return 1;
        }

        if (a.equals(b)) {
            return 0;
        }

        String strA = a.toString();
        String strB = b.toString();

        Matcher matcherA = patternA.matcher(strA);
        Matcher matcherB = patternB.matcher(strB);

        Map<Integer, Integer> indexMapA = new HashMap<Integer, Integer>();
        Map<Integer, Integer> indexMapB = new HashMap<Integer, Integer>();

        while (matcherA.find()) {
            indexMapA.put(matcherA.start(), matcherA.end());
        }

        while (matcherB.find()) {
            indexMapB.put(matcherB.start(), matcherB.end());
        }

        int iA = 0;
        int iB = 0;


        while (true) {

            Character cA = getCharacter(strA, iA);
            Character cB = getCharacter(strB, iB);

            while (isSpaceChar(cA)) {
                cA = getCharacter(strA, ++iA);
            }

            while (isSpaceChar(cB)) {
                cB = getCharacter(strB, ++iB);
            }

            if (indexMapA.containsKey(iA) && indexMapB.containsKey(iB)) {
                String tempA = strA.substring(iA, indexMapA.get(iA));
                String tempB = strB.substring(iB, indexMapB.get(iB));

                int compareResult = Double.compare(Double.parseDouble(tempA), Double.parseDouble(tempB));
                if (compareResult != 0) {
                    return compareResult;
                }

                iA = indexMapA.get(iA);
                iB = indexMapB.get(iB);

                continue;
            }

            if (cA == null && cB == null) {
                return 0;
            }

            if (cA == null) {
                return -1;
            }

            if (cB == null) {
                return 1;
            }

            if (!careCase) {
                cA = Character.toUpperCase(cA);
                cB = Character.toUpperCase(cB);
            }

            int tempResult = cA.compareTo(cB);
            if (tempResult != 0) {
                return tempResult;
            }

            ++iA;
            ++iB;
        }
    }


    /**
     * 获取字符
     * @param var
     * @param index
     * @return
     */
    private Character getCharacter(String var, int index) {
        if (var == null || index >= var.length()) {
            return null;
        }

        return var.charAt(index);
    }

    /**
     * 判断是否是空格
     * @param var
     * @return
     */
    private boolean isSpaceChar(Character var) {
        return var != null && Character.isSpaceChar(var);
    }

}

问题

由于把‘-’号和‘+’号作为了数字匹配的因素之一,所以在应对诸如时间格式如“2017-04-25”或者非数字语义的字符串如“中国-1个美丽的国度”时,会出现排序结果非我所愿的情况。看样子直接通过某一算法来达到完全智能的排序是不可能的,解决办法可以针对不同的业务场景来装配不同的比较器,或者用不同的Wrapper包装对象达到期望的结果。

github:https://github.com/zhencygo/java/tree/master/algorithm

相关文章

  • 探究Java自然排序算法

    说明 现实生活中有很多场景需要用到“自然排序”的算法,比如对金钱表示的排序:“¥165.2,¥-365.03,¥+...

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • 排序算法(四) 希尔排序(插入排序的进化)

    参考Java排序算法(四):希尔排序常见排序算法 - 希尔排序 (Shell Sort) 希尔排序算法是按其设计者...

  • java 实现排序算法之「插入排序」

    java 实现排序算法系列 这是 Java 实现排序算法的第三篇文章——插入排序算法。插入排序可以说成是「一类」简...

  • java排序方法资料

    java排序,效率高的是哪种排序方法 JAVA快速排序(高效) java中常用的几种排序算法 相关代码: /* *...

  • 排序算法-堆排序

    参考: Java排序算法(五):堆排序 【算法与数据结构】图说堆排序 【数据结构】排序算法:希尔、归并、快速、堆排...

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现。参考文章:十大经典排序算法总结(Java语言实现)快速排序算法...

  • Java常用排序算法/程序员必须掌握的8大排序算法

    Java常用排序算法/程序员必须掌握的8大排序算法

  • 排序算法

    常见排序算法比较 参考资料:各种排序算法比较 参考资料:快速排序算法 必须知道的八大种排序算法【java实现】(一...

网友评论

      本文标题:探究Java自然排序算法

      本文链接:https://www.haomeiwen.com/subject/ycdbzttx.html