첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

■ Array 클래스의 Sort 정적 메소드를 사용해 자연 정렬을 하는 방법을 보여준다.

TestProject.zip
0.00MB

▶ 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
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요