【分享】Java中文字符串包含数字排序(自然语义)

前言:

根据需求,出现分类10,分类7,分类03类似的数据时,需要排程分类03,分类7,分类10,可参考如下实现。

原文鸣谢: https://www.cnblogs.com/interdrp/p/8970593.html

效果展示:

核心算法:

     1.实现Comparetor,重写compare 原本是按照给定的排序规则,逐字符比较。需要改写成我们的规则

     2.找到数字元素,进行比较。注意是同位置。

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

public class Demo {

    public static void main(String[] args) {
        String fileNames[] = {"分类1", "分类22", "分类081", "分类444", "分组", "分组1", "分类0070000000000000000000000000", "分组03", "我的祖国872", "分组009", "我的家乡99", "分组009开幕001", "分组009开幕12"};
        char chFileNames[][] = new char[fileNames.length][];
        String[] oldSortedNames = new String[fileNames.length];
        for (int i = 0; i < fileNames.length; i++) {
            chFileNames[i] = fileNames[i].toCharArray();
            oldSortedNames[i] = fileNames[i];
        }
        Arrays.sort(chFileNames, ChsLogicCmp);
        String line = null;
        for (int i = 0; i < fileNames.length; i++) {
            System.out.println(chFileNames[i]);
        }


    }

    static Comparator<char[]> ChsLogicCmp = new Comparator<char[]>() {
        class Int {
            public int i;
        }

        public int findDigitEnd(char[] arrChar, Int at) {
            int k = at.i;
            char c = arrChar[k];
            boolean bFirstZero = (c == '0');
            while (k < arrChar.length) {
                c = arrChar[k];
                //first non-digit which is a high chance.
                if (c > '9' || c < '0') {
                    break;
                } else if (bFirstZero && c == '0') {
                    at.i++;
                }
                k++;
            }
            return k;
        }

        @Override
        public int compare(char[] a, char[] b) {
            if (a != null || b != null) {
                Int aNonzeroIndex = new Int();
                Int bNonzeroIndex = new Int();
                int aIndex = 0, bIndex = 0,
                        aComparedUnitTailIndex, bComparedUnitTailIndex;
                while (aIndex < a.length && bIndex < b.length) {
                    //aIndex <
                    aNonzeroIndex.i = aIndex;
                    bNonzeroIndex.i = bIndex;
                    aComparedUnitTailIndex = findDigitEnd(a, aNonzeroIndex);
                    bComparedUnitTailIndex = findDigitEnd(b, bNonzeroIndex);
                    //compare by number
                    if (aComparedUnitTailIndex > aIndex && bComparedUnitTailIndex > bIndex) {
                        int aDigitIndex = aNonzeroIndex.i;
                        int bDigitIndex = bNonzeroIndex.i;
                        int aDigit = aComparedUnitTailIndex - aDigitIndex;
                        int bDigit = bComparedUnitTailIndex - bDigitIndex;
                        //compare by digit
                        if (aDigit != bDigit)
                            return aDigit - bDigit;
                        //the number of their digit is same.
                        while (aDigitIndex < aComparedUnitTailIndex) {
                            if (a[aDigitIndex] != b[bDigitIndex])
                                return a[aDigitIndex] - b[bDigitIndex];
                            aDigitIndex++;
                            bDigitIndex++;
                        }
                        //if they are equal compared by number, compare the number of '0' when start with "0"
                        //ps note: paNonZero and pbNonZero can be added the above loop "while", but it is changed meanwhile.
                        //so, the following comparsion is ok.
                        aDigit = aNonzeroIndex.i - aIndex;
                        bDigit = bNonzeroIndex.i - bIndex;
                        if (aDigit != bDigit)
                            return aDigit - bDigit;
                        aIndex = aComparedUnitTailIndex;
                        bIndex = bComparedUnitTailIndex;
                    } else {
                        if (a[aIndex] != b[bIndex])
                            return a[aIndex] - b[bIndex];
                        aIndex++;
                        bIndex++;
                    }

                }

            }
            return a.length - b.length;
        }

    };
}

posted @ 2021-08-26 10:48  虹梦未来  阅读(120)  评论(0编辑  收藏  举报  来源