728x90
반응형
728x170
■ 자연 정렬을 하는 방법을 보여준다.
▶ NaturalSortingComparer.cs
using System.Text.RegularExpressions;
namespace TestProject;
/// <summary>
/// 자연 정렬 비교자
/// </summary>
/// <typeparam name="TItem">항목 타입</typeparam>
public class NaturalSortingComparer<TItem> : IComparer<string>, IDisposable
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 딕셔너리
/// </summary>
private Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
/// <summary>
/// 오름차순 여부
/// </summary>
private bool isAscending;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - NaturalSortingComparer(isAscending)
/// <summary>
/// 생성자
/// </summary>
/// <param name="isAscending">오름차순 여부</param>
public NaturalSortingComparer(bool isAscending = true)
{
this.isAscending = isAscending;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 비교하기 - Compare(source1, source2)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>비교 결과</returns>
public int Compare(string source1, string source2)
{
throw new NotImplementedException();
}
#endregion
#region 비교하기 - IComparer<string>.Compare(source1, source2)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>비교 결과</returns>
int IComparer<string>.Compare(string source1, string source2)
{
if(source1 == source2)
{
return 0;
}
string[] tokenArray1;
string[] tokenArray2;
if(!this.dictionary.TryGetValue(source1, out tokenArray1))
{
tokenArray1 = Regex.Split(source1.Replace(" ", ""), "([0-9]+)");
this.dictionary.Add(source1, tokenArray1);
}
if(!this.dictionary.TryGetValue(source2, out tokenArray2))
{
tokenArray2 = Regex.Split(source2.Replace(" ", ""), "([0-9]+)");
this.dictionary.Add(source2, tokenArray2);
}
int result;
for(int i = 0; i < tokenArray1.Length && i < tokenArray2.Length; i++)
{
if(tokenArray1[i] != tokenArray2[i])
{
result = ComparePart(tokenArray1[i], tokenArray2[i]);
return isAscending ? result : -result;
}
}
if(tokenArray2.Length > tokenArray1.Length)
{
result = 1;
}
else if(tokenArray1.Length > tokenArray2.Length)
{
result = -1;
}
else
{
result = 0;
}
return isAscending ? result : -result;
}
#endregion
#region 리소스 해제하기 - Dispose()
/// <summary>
/// 리소스 해제하기
/// </summary>
public void Dispose()
{
this.dictionary.Clear();
this.dictionary = null;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 부분 비교하기 - ComparePart(source1, source2)
/// <summary>
/// 부분 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>부분 비교 결과</returns>
private static int ComparePart(string source1, string source2)
{
int value1;
int value2;
if(!int.TryParse(source1, out value1))
{
return source1.CompareTo(source2);
}
if(!int.TryParse(source2, out value2))
{
return source1.CompareTo(source2);
}
return value1.CompareTo(value2);
}
#endregion
}
▶ Program.cs
namespace TestProject;
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
string[] sourceArray = new string[]
{
"a4",
"a3",
"a2",
"a10",
"b5",
"b4",
"b400",
"1",
"C1d",
"c1d2"
};
Array.Sort(sourceArray, new NaturalSortingComparer<string>());
foreach(string source in sourceArray)
{
Console.WriteLine(source);
}
}
#endregion
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON/.NET6] IEquatable<T> 인터페이스 사용하기 (0) | 2022.10.19 |
---|---|
[C#/COMMON/.NET6] String 클래스 : PadLeft 메소드를 사용해 반복 문자열 구하기 (0) | 2022.10.18 |
[C#/COMMON/.NET6] StringBuilder 클래스 : Insert 메소드를 사용해 반복 문자열 구하기 (0) | 2022.10.18 |
[C#/COMMON/.NET6] 문자열 반복하기 (0) | 2022.10.18 |
[C#/COMMON/.NET6] String 클래스 : 생성자를 사용해 반복 문자열 구하기 (0) | 2022.10.18 |
[C#/COMMON/.NET6] 자연 정렬하기 (0) | 2022.10.15 |
[C#/COMMON/.NET6] 윈도우즈 실행 파일 형식(PE32/PE32+) 구하기 (0) | 2022.10.15 |
[C#/COMMON/.NET6] 프로젝트에서 UNSAFE 모드 설정하기 (0) | 2022.10.14 |
[C#/COMMON/.NET6] 공백 문자 제거하기 (UNSAFE 모드) (0) | 2022.10.14 |
[C#/COMMON/.NET6] 공백 문자 제거하기 (0) | 2022.10.14 |
댓글을 달아 주세요