zoukankan      html  css  js  c++  java
  • 含字母数字的字符串排序算法,仿Windows文件名排序算法

    不废话,上排序前后对比:

    类似与windows的目录文件排序,分几种版本C++/C#/JAVA给大家:

    1、Java版

    package com.eam.util;
    /* * The Alphanum Algorithm is an improved sorting algorithm for strings * containing numbers. Instead of sorting numbers in ASCII order like * a standard sort, this algorithm sorts numbers in numeric order. * * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com * * Released under the MIT License - https://opensource.org/licenses/MIT * * Copyright 2007-2017 David Koelle * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; /** * This is an updated version with enhancements made by Daniel Migowski, * Andre Bogus, and David Koelle. Updated by David Koelle in 2017. * * To use this class: * Use the static "sort" method from the java.util.Collections class: * Collections.sort(your list, new AlphanumComparator()); */ public class AlphanumComparator implements Comparator<String> { private final boolean isDigit(char ch) { return ((ch >= 48) && (ch <= 57)); } /** Length of string is passed in for improved efficiency (only need to calculate it once) **/ private final String getChunk(String s, int slength, int marker) { StringBuilder chunk = new StringBuilder(); char c = s.charAt(marker); chunk.append(c); marker++; if (isDigit(c)) { while (marker < slength) { c = s.charAt(marker); if (!isDigit(c)) { break; } chunk.append(c); marker++; } } else { while (marker < slength) { c = s.charAt(marker); if (isDigit(c)) { break; } chunk.append(c); marker++; } } return chunk.toString(); } @Override public int compare(String s1, String s2) { if ((s1 == null) || (s2 == null)) { return 0; } int thisMarker = 0; int thatMarker = 0; int s1Length = s1.length(); int s2Length = s2.length(); while (thisMarker < s1Length && thatMarker < s2Length) { String thisChunk = getChunk(s1, s1Length, thisMarker); thisMarker += thisChunk.length(); String thatChunk = getChunk(s2, s2Length, thatMarker); thatMarker += thatChunk.length(); // If both chunks contain numeric characters, sort them numerically int result = 0; if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) { // Simple chunk comparison by length. int thisChunkLength = thisChunk.length(); result = thisChunkLength - thatChunk.length(); // If equal, the first different number counts if (result == 0) { for (int i = 0; i < thisChunkLength; i++) { result = thisChunk.charAt(i) - thatChunk.charAt(i); if (result != 0) { return result; } } } } else { result = thisChunk.compareTo(thatChunk); } if (result != 0) { return result; } } return s1Length - s2Length; } /** * Shows an example of how the comparator works. * Feel free to delete this in your own code! */ public static void main(String[] args) { List<String> values = Arrays.asList("ASH_1", "ASH_11", "ASH_12", "ASH_100", "HJ1", "HJ_2", "HJ_10", "HJ_100", "1#定型机", "2#定型机", "10#定型机","染色机01#", "染色机02#", "染色机10#"); System.out.println(values.stream().sorted(new AlphanumComparator()).collect(Collectors.joining(" "))); } }

    2、C#版

    /*
     * The Alphanum Algorithm is an improved sorting algorithm for strings
     * containing numbers.  Instead of sorting numbers in ASCII order like
     * a standard sort, this algorithm sorts numbers in numeric order.
     *
     * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
     *
     * Based on the Java implementation of Dave Koelle's Alphanum algorithm.
     * Contributed by Jonathan Ruckwood <jonathan.ruckwood@gmail.com>
     *
     * Adapted by Dominik Hurnaus <dominik.hurnaus@gmail.com> to
     *   - correctly sort words where one word starts with another word
     *   - have slightly better performance
     *
     * Released under the MIT License - https://opensource.org/licenses/MIT
     *
     * Permission is hereby granted, free of charge, to any person obtaining
     * a copy of this software and associated documentation files (the "Software"),
     * to deal in the Software without restriction, including without limitation
     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     * and/or sell copies of the Software, and to permit persons to whom the
     * Software is furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included
     * in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     * USE OR OTHER DEALINGS IN THE SOFTWARE.
     *
     */
    using System;
    using System.Collections;
    using System.Text;
    
    /*
     * Please compare against the latest Java version at http://www.DaveKoelle.com
     * to see the most recent modifications
     */
    namespace AlphanumComparator
    {
        public class AlphanumComparator : IComparer
        {
            private enum ChunkType {Alphanumeric, Numeric};
            private bool InChunk(char ch, char otherCh)
            {
                ChunkType type = ChunkType.Alphanumeric;
    
                if (char.IsDigit(otherCh))
                {
                    type = ChunkType.Numeric;
                }
    
                if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
                    || (type == ChunkType.Numeric && !char.IsDigit(ch)))
                {
                    return false;
                }
    
                return true;
            }
    
            public int Compare(object x, object y)
            {
                String s1 = x as string;
                String s2 = y as string;
                if (s1 == null || s2 == null)
                {
                    return 0;
                }
    
                int thisMarker = 0, thisNumericChunk = 0;
                int thatMarker = 0, thatNumericChunk = 0;
    
                while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
                {
                    if (thisMarker >= s1.Length)
                    {
                        return -1;
                    }
                    else if (thatMarker >= s2.Length)
                    {
                        return 1;
                    }
                    char thisCh = s1[thisMarker];
                    char thatCh = s2[thatMarker];
    
                    StringBuilder thisChunk = new StringBuilder();
                    StringBuilder thatChunk = new StringBuilder();
    
                    while ((thisMarker < s1.Length) && (thisChunk.Length==0 ||InChunk(thisCh, thisChunk[0])))
                    {
                        thisChunk.Append(thisCh);
                        thisMarker++;
    
                        if (thisMarker < s1.Length)
                        {
                            thisCh = s1[thisMarker];
                        }
                    }
    
                    while ((thatMarker < s2.Length) && (thatChunk.Length==0 ||InChunk(thatCh, thatChunk[0])))
                    {
                        thatChunk.Append(thatCh);
                        thatMarker++;
    
                        if (thatMarker < s2.Length)
                        {
                            thatCh = s2[thatMarker];
                        }
                    }
    
                    int result = 0;
                    // If both chunks contain numeric characters, sort them numerically
                    if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
                    {
                        thisNumericChunk = Convert.ToInt32(thisChunk.ToString());
                        thatNumericChunk = Convert.ToInt32(thatChunk.ToString());
    
                        if (thisNumericChunk < thatNumericChunk)
                        {
                            result = -1;
                        }
    
                        if (thisNumericChunk > thatNumericChunk)
                        {
                            result = 1;
                        }
                    }
                    else
                    {
                        result = thisChunk.ToString().CompareTo(thatChunk.ToString());
                    }
    
                    if (result != 0)
                    {
                        return result;
                    }
                }
    
                return 0;
            }
        }
    }

     排序后:

    1#定型机  2#定型机  10#定型机  ASH_1  ASH_11  ASH_12  ASH_100  HJ1  HJ_2  HJ_10  HJ_100  染色机01#  染色机02#  染色机10#
  • 相关阅读:
    【原】error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string'
    【原】开发路上疑难BUG调试记录
    【转】XCode: duplicate symbol 解决方案
    【原】就IOS发布app时如何保护文本资源的一个方法
    【原】xcode5.0升级5.1遇到的clang: error: unknown argument: '-fobj-arc'错误
    【转】生产者与消费者
    安卓快速排序与冒泡排序
    数据结构之算法时间复杂度
    常见数据结构与算法整理总结(上)
    Activity的onPause()、onStop()和onDestroy()里要做的事情
  • 原文地址:https://www.cnblogs.com/winchance/p/15632850.html
Copyright © 2011-2022 走看看