728x90
반응형
728x170
■ Array 클래스의 Sort 정적 메소드를 사용해 자연 정렬을 하는 방법을 보여준다.
▶ SortHelper.cs
using System.Globalization;
namespace TestProject
{
/// <summary>
/// 정렬 헬퍼
/// </summary>
public class SortHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 비교하기 - Compare(source1, source2, cultureInfo, options)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <param name="cultureInfo">문화 정보</param>
/// <param name="options">비교 옵션</param>
/// <returns>비교 결과</returns>
public static int Compare(string source1, string source2, CultureInfo cultureInfo, CompareOptions options)
{
CompareInfo compareInfo = cultureInfo.CompareInfo;
int index1 = 0;
int index2 = 0;
int result = 0;
int resultWeight = 0;
while(index1 < source1.Length && index2 < source2.Length)
{
bool isDigit1 = char.IsDigit(source1[index1]);
bool isDigit2 = char.IsDigit(source2[index2]);
if(isDigit1 != isDigit2)
{
return compareInfo.Compare(source1, index1, source2, index2, options);
}
else if(!isDigit1 && !isDigit2)
{
int nextIndex1 = index1 + 1;
int nextIndex2 = index2 + 1;
while(nextIndex1 < source1.Length && !Char.IsDigit(source1[nextIndex1])) nextIndex1++;
while(nextIndex2 < source2.Length && !Char.IsDigit(source2[nextIndex2])) nextIndex2++;
int temporaryResult = compareInfo.Compare(source1, index1, nextIndex1 - index1, source2, index2, nextIndex2 - index2, options);
if(temporaryResult != 0)
{
string section1 = source1.Substring(index1, nextIndex1 - index1);
string section2 = source2.Substring(index2, nextIndex2 - index2);
if(compareInfo.Compare(section1 + "1", section2 + "2", options) == compareInfo.Compare(section1 + "2", section2 + "1", options))
{
return compareInfo.Compare(source1, index1, source2, index2, options);
}
else if(resultWeight < 1)
{
result = temporaryResult;
resultWeight = 1;
}
}
index1 = nextIndex1;
index2 = nextIndex2;
}
else
{
char zeroCharacter1 = (char)(source1[index1] - (int)char.GetNumericValue(source1[index1]));
char zeroCharacter2 = (char)(source2[index2] - (int)char.GetNumericValue(source2[index2]));
int index3 = index1;
int index4 = index2;
while(index3 < source1.Length && source1[index3] == zeroCharacter1) index3++;
while(index4 < source2.Length && source2[index4] == zeroCharacter2) index4++;
int resultIfSameLength = 0;
do
{
isDigit1 = index3 < source1.Length && Char.IsDigit(source1[index3]);
isDigit2 = index4 < source2.Length && Char.IsDigit(source2[index4]);
int number1 = isDigit1 ? (int)char.GetNumericValue(source1[index3]) : 0;
int number2 = isDigit2 ? (int)char.GetNumericValue(source2[index4]) : 0;
if(isDigit1 && (char)(source1[index3] - number1) != zeroCharacter1)
{
isDigit1 = false;
}
if(isDigit2 && (char)(source2[index4] - number2) != zeroCharacter2)
{
isDigit2 = false;
}
if(isDigit1 && isDigit2)
{
if(number1 != number2 && resultIfSameLength == 0)
{
resultIfSameLength = number1 < number2 ? -1 : 1;
}
index3++;
index4++;
}
}
while(isDigit1 && isDigit2);
if(isDigit1 != isDigit2)
{
return isDigit1 ? 1 : -1;
}
else if(resultIfSameLength != 0)
{
return resultIfSameLength;
}
int index5 = index3 - index1;
int index6 = index4 - index2;
if(index5 != index6)
{
return index5 > index6 ? -1 : 1;
}
else if(zeroCharacter1 != zeroCharacter2 && resultWeight < 2)
{
result = compareInfo.Compare(source1, index1, 1, source2, index2, 1, options);
resultWeight = 2;
}
index1 = index3;
index2 = index4;
}
}
if(index1 < source1.Length || index2 < source2.Length)
{
return index1 < source1.Length ? 1 : -1;
}
else if(result != 0)
{
return result;
}
return 0;
}
#endregion
#region 비교하기 - Compare(source1, source2)
/// <summary>
/// 비교하기
/// </summary>
/// <param name="source1">소스 문자열 1</param>
/// <param name="source2">소스 문자열 2</param>
/// <returns>비교 결과</returns>
public static int Compare(string source1, string source2)
{
return Compare(source1, source2, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
}
#endregion
}
}
▶ Program.cs
namespace TestProject;
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
private static void Main()
{
string[] filePathArray = Directory.GetFiles("D:\\temp");
Array.Sort(filePathArray, SortHelper.Compare);
foreach(string filePath in filePathArray)
{
Console.WriteLine(filePath);
}
}
#endregion
}
728x90
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON/.NET6] 이진 검색 트리(Binary Search Tree) 사용하기 (0) | 2022.08.26 |
---|---|
[C#/COMMON/.NET6] 제곱근 계산하기 (Math.Sqrt 정적 메소드 미사용) (0) | 2022.08.25 |
[C#/COMMON/.NET6] implicit operator 키워드 : 암시적 변환 사용하기 (0) | 2022.08.19 |
[C#/COMMON/.NET6] 컬럼 기준으로 2차원 배열 정렬하기 (0) | 2022.08.19 |
[C#/COMMON/.NET6] 가변 배열 사용하기 (0) | 2022.08.19 |
[C#/COMMON] Regex 클래스 : Replace 정적 메소드를 사용해 다중 공백 문자열을 단일 공백 문자열로 대체하기 (0) | 2022.07.28 |
[C#/COMMON/.NET6] String 클래스 : 다중 공백 문자열을 단일 공백 문자열로 대체하기 (0) | 2022.07.28 |
[C#/COMMON] Regex 클래스 : Replace 메소드를 사용해 다중 공백 문자열을 단일 공백 문자열로 대체하기 (0) | 2022.07.28 |
[C#/COMMON] DateTime 구조체 : 두 날짜 사이에서 개월 수 구하기 (0) | 2022.07.28 |
[C#/COMMON/.NET6] 배열 병합하기 (0) | 2022.07.28 |
댓글을 달아 주세요