문제

문자열을 정렬하는 표준 방식에 익숙해 져서 Windows가 이름으로 파일을 일종의 고급 방식으로 정렬한다는 것을 알았을 때 놀랐습니다. 예를 들어 보겠습니다.

트랙 1.mp3
track2.mp3
트랙 10.mp3
Track20.mp3

나는 그 이름이 문자와 숫자에 따라 (정렬 중에) 비교된다고 생각합니다.

반면에 다음은 표준 방식으로 정렬 된 동일한 목록입니다.
트랙 1.mp3
트랙 10.mp3
track2.mp3
Track20.mp3

델파이에서 비교 알로 로리즘을 만들고 싶습니다. 처음에 나는 문자 인 동안 두 줄의 연속 문자를 비교하기에 충분할 것이라고 생각했습니다. 숫자가 두 줄의 일부 위치에서 발견되면 숫자를 형성하고 숫자를 비교하기 위해 다음과 같은 숫자를 읽습니다.

예를 들기 위해 "Track10"및 "Track2"문자열을 이런 방식으로 비교하겠습니다.
1) 문자가 동일하고 문자 인 동안 문자를 읽으십시오 : "트랙", "트랙"
2) 숫자가 발견되면 다음 숫자를 모두 읽으십시오. "10", "2"
2a) 동일하다면 1으로 이동하거나 그렇지 않으면 마무리하십시오.
10은 2보다 크기 때문에 "Track10"은 "Track2"보다 큽니다.

테스트 중에 Windows가 "Track010"이 "Track10"보다 낮은 "Track010"이라는 것을 알기 전까지는 모든 것이 잘 될 것 같았으며, 첫 번째는 더 길어서 더 크다고 생각했습니다 (내 알고리즘에 따르면 언급하지 않았습니다. 문자열이 같을 것입니다.

Windows가 이름으로 파일을 정확히 정렬하는 방법을 제공하거나 기반으로 할 수있는 즉시 사용 가능한 알고리즘 (모든 프로그래밍 언어)이있는 방법을 제공 할 수 있습니까?

정말 감사합니다!
마리우스

도움이 되었습니까?

해결책

Jeff는 코딩 공포에 관한 기사를 썼습니다. 이것은 ... 불리운다 자연 분류, 당신은 숫자 그룹을 단일 "문자"로 효과적으로 취급합니다. 태양 아래의 모든 언어에는 구현이 있지만 이상하게도 대부분의 언어 표준 라이브러리에 내장되지는 않습니다.

다른 팁

내가 찾은 가장 쉬운 방법은 당신이 원하는 문자열을 격리하는 것이 었습니다. OP의 경우 path.getfilenamewithoutextension (), 비 독점을 제거하고 int로 변환하고 정렬합니다. LINQ와 일부 확장 방법을 사용하면 1 라이너입니다. 제 경우에는 디렉토리를 진행했습니다.

Directory.GetDirectories(@"a:\b\c").OrderBy(x => x.RemoveNonDigits().ToIntOrZero())

Removenondigits 및 Tointorzero가 확장 방법 인 경우 :

public static string RemoveNonDigits(this string value) {
    return Regex.Replace(value, "[^0-9]", string.Empty);
}

public static int ToIntOrZero(this string toConvert) {
    try {
        if (toConvert == null || toConvert.Trim() == string.Empty) return 0;            
        return int.Parse(toConvert);
    } catch (Exception) {
        return 0;
    }
}

확장 방법은 어디에서나 사용하는 일반적인 도구입니다. ymmv.

모든 종류의 어머니 :

ls '*.mp3' | sort --version-sort

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top