알 수없는 밑으로 표현 된 숫자 정렬


13

문자열 목록이 주어지면 어떤 염기가 사용되는지 모른 채 목록을 숫자로 정렬하십시오. 숫자의 값도 알 수 없습니다 ( '1'> '2').

자릿수 값을 알 수 없으므로 Benford의 법칙 (또는 첫 번째 자릿수 법칙)을 사용하여 자릿수의 상대 값을 결정하십시오. Benford의 법칙을 따르는 분포의 경우 값이 작은 숫자가 값이 큰 숫자보다 선행 숫자로 더 자주 나타납니다.

규칙

  • 이것은
  • 문자열 목록은 선택한 소스 (stdin, variable, file, user 등)에서 올 수 있습니다.
  • 문자열은 ASCII 문자로 제한됩니다.
  • 선행 문자로 표시되지 않는 문자는 가장 높은 값을 갖습니다. (0이 없다고 가정하고 선행 빈도로 엄격하게 정렬하십시오.)
  • 다른 문자와 같은 횟수만큼 선행 숫자로 나타나는 문자는 가중치가 동일합니다.

분류되지 않은

['c','ca','ac','cc','a','ccc','cx','cz','cy']

정렬

['c','a','cc','ca','cz','cy','cx','ac','ccc']

참고 예에서 'cz', 'cy'그리고 'cx'5, 6 및 숫자 보낸 임의의 순서로 7 요소로 나타날 수 'x', 'y''z'똑같이 가중된다.


"문자열은 ASCII 문자로 제한됩니다." 이 예에서는 영숫자 만 표시합니다 (실제로는 알파벳 문자 만 표시). 모든 ASCII 문자 또는 [0-9a-zA-Z] 만 의미합니까? 소문자는 대문자와 동일하거나 다르게 계산됩니까?
Joshua Taylor

모든 ASCII 문자가 지원되어야하며 대문자와 소문자가 다릅니다.
Rynant 2016 년

답변:


7

파이썬 (59) 108 112

sorted(a,None,lambda x:(-len(x),map(zip(*a)[0].count,x)),1)

입력은 list로 제공 a되며이 표현식은 정렬 된 목록 (변수에 지정할 +2 문자)을 생성합니다. 부정 된 길이를 기준으로 목록 을 역순 으로 정렬 한 다음 빈도를 기준으로 정렬합니다 .


+1 훌륭합니다. 단일 표현으로 공간을 효율적으로 수행 할 수 있다고 생각하지 않았습니다.
seequ

좋은! 에 대해 몰랐 zip습니다 None. 을 사용하는 Python 3에서는 작동하지 않지만 itertools.zip_longest.
Rynant

None파이썬 3의 정수와 비교할 수 없으므로 어쨌든 실패합니다.
nneonneo 2016 년

@nneonneo 맞습니다 fillvalue. 가장 작은 값보다 작은 값으로 설정해야합니다.
Rynant

그리고 내가 알고 있다고 생각 뭔가 아니 - 파이썬에 대한합니다. 코드를 좀 더 자세하게 설명해 주시겠습니까? 나는 매우 행복합니다-파이썬 초보자.
flawr

3

루비, 65

f=->a{a.sort_by{|s|[s.size,s.chars.map{|c|a.count{|t|t[0]!=c}}]}}

문자열의 크기를 사전 식으로 정렬 한 다음 각 문자의 빈도를 선행 숫자가 아닌 것으로 정렬합니다.


0

자바 (261)

void s(String[]s){int[]a=new int[128];for(String t:s)a[t.charAt(0)]++;java.util.Arrays.sort(s,(o,p)->{int j=o.length()-p.length();if(j!=0)return j;for(int i=0;i<Math.min(o.length(),p.length());i++){j=a[p.charAt(i)]-a[o.charAt(i)];if(j!=0)return j;}return 0;});}

void s(String[] s) {
    int[] a = new int[128];
    for (String t : s) {
        a[t.charAt(0)]++;
    }
    java.util.Arrays.sort(s, (o, p) -> {
        int j = o.length() - p.length();
        if (j != 0) {
            return j;
        }
        for (int i = 0; i < Math.min(o.length(), p.length()); i++) {
            j = a[p.charAt(i)] - a[o.charAt(i)];
            if (j != 0) {
                return j;
            }
        }
        return 0;
    });
}

이 메소드는 문자열 배열을 가져 와서 배열을 정렬합니다. 구현에 대해 멋진 것은 없지만 Java 8에 추가 된 람다 식을 사용합니다.


0

자바 스크립트 (E6) 147

F=i=>(f={},i.map(x=>(f[x[0]]=-~f[x[0]])),i.map(x=>[x,[...x].map(y=>1e9-~f[y]+'')]).sort((a,b,d=a[0].length-b[0].length)=>d||a[1]<b[1]).map(x=>x[0]))

한도

최대 1000000000의 빈도 값 : 정렬을 위해 빈도 값은 큰 패딩 문자열로 병합됩니다.

언 골프

F=i=>(
  f={}, //init frequency map
  i.map(x => (f[x[0]]=-~f[x[0]])), // build frequency map
  i.map(x => [x, [...x].map(y=>1e9-~f[y]+'')]) // add frequency info to each element of input list
 .sort((a,b,d=a[0].length-b[0].length)=>d || a[1]<b[1]) // then sort by lenght and frequency
 .map( x => x[0]) // throw away frequency info
)

X-~원래 숫자 X가 정의되지 않았거나 NaN 인 경우에도 각주 1 씩 증가

용법

F(['c','ca','ac','cc','a','ccc','cx','cz','cy'])

산출: ["c", "a", "cc", "ca", "cx", "cz", "cy", "ac", "ccc"]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.