含字母数字的字符串排序算法,仿Windows文件名排序算法
2024-10-21 23:27:34
不废话,上排序前后对比:
类似与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#
最新文章
- MSDN文档篇
- 《微软互联网信息服务(IIS) 最佳实践》已上市,欢迎选购!
- 6、ASP.NET MVC入门到精通——ASP.Net的两种开发方式
- SQL删除约束
- jquery实现的个性网站首页 详细信息
- Python调试工具-Spyder
- uva 484 - The Department of Redundancy Department
- 第十一届GPCT杯大学生程序设计大赛完美闭幕
- python3.4 使用pymssql 乱码
- C++ 关于字符串总结(持续更新)
- EffectiveC++ 第2章 构造/析构/赋值运算
- xpath简单实用
- chrome 抓包的小功能--preserve log (记录页面跳转后,所有的抓包记录)
- 2.2 数据的图形描绘以及处理(QQplot,归一化)
- JSP中的内置标记(JSP动作)和 EL表达式
- Android LayoutCast 初探
- BZOJ 2648 kd-tree模板
- windows 网页打不开github网站
- chrome跨域访问
- c# 数据拼接成键值对格式