Nummern sortieren, die in einer unbekannten Basis dargestellt werden

13

Sortieren Sie die Liste anhand einer Liste von Zeichenfolgen als Zahlen, ohne zu wissen, welche Basis verwendet wird. Die Werte der Ziffern sind ebenfalls unbekannt (es ist möglich, dass '1'> '2').

Da die Werte von Ziffern unbekannt sind, verwenden Sie das Benford-Gesetz (oder das Gesetz der ersten Ziffer), um den relativen Wert der Ziffern zu bestimmen. Bei Verteilungen, die dem Benfordschen Gesetz folgen, werden Ziffern mit niedrigeren Werten häufiger als führende Ziffern angezeigt als Ziffern mit höheren Werten.

Regeln

  • Das ist
  • Die Liste der Zeichenfolgen kann von einer Quelle Ihrer Wahl stammen (stdin, Variable, Datei, Benutzer usw.).
  • Zeichenfolgen sind auf ASCII-Zeichen beschränkt.
  • Zeichen, die nicht als führende Zeichen erscheinen, haben die höchsten Werte. (Nehmen wir an, dass es keine Nullen gibt und sortieren Sie streng nach der führenden Frequenz.)
  • Zeichen, die als führende Ziffern so oft vorkommen wie andere Zeichen, werden gleich gewichtet.

Beispiel

Unsortiert

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

Sortiert

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

Hinweis: In dem Beispiel 'cz', 'cy'und 'cx'wie der 5., 6. und 7. Elemente in beliebiger Reihenfolge , da die Ziffern erscheinen können 'x', 'y'und 'z'sind gleich gewichtet.

Rynant
quelle
"Zeichenfolgen sind auf ASCII-Zeichen beschränkt." Ihr Beispiel zeigt nur alphanumerische Zeichen (eigentlich nur alphabetische Zeichen). Meinen Sie alle ASCII-Zeichen oder nur [0-9a-zA-Z] und zählen Kleinbuchstaben gleich oder verschieden von Großbuchstaben?
Joshua Taylor
Alle ASCII-Zeichen sollten unterstützt werden und Groß- und Kleinbuchstaben sind unterschiedlich.
Rynant

Antworten:

7

Python, 59 108 112

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

Die Eingabe wird als Liste bereitgestellt a, und dieser Ausdruck erzeugt die sortierte Liste (+2 Zeichen, die einer Variablen zugewiesen werden sollen). Dies sortiert die Liste in umgekehrter Reihenfolge nach negierter Länge und dann nach Häufigkeit.

nneonneo
quelle
+1 Schön gemacht. Ich hätte nicht gedacht, dass es mit einem Ausdruck effizient möglich ist, Platz zu schaffen.
Siehe auch
Nett! Ich wusste nicht zipmit None. In Python 3 funktioniert das allerdings nicht itertools.zip_longest.
Rynant
Nonekann nicht mit ganzen Zahlen in Python 3 verglichen werden, daher würde es trotzdem fehlschlagen.
Nneonneo
@nneonneo Richtig, fillvaluemüsste auf etwas weniger als den kleinsten Wert gesetzt werden.
Rynant
Und ich dachte, ich wüsste etwas über Python-Nope. Könnten Sie Ihren Code etwas ausführlicher erklären? Ich würde mich sehr freuen - Python-Neuling hier.
Fehler
3

Rubin, 65

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

Sortiert lexikografisch nach der Größe der Zeichenfolge, wobei die Häufigkeit der einzelnen Zeichen nicht die führende Ziffer ist.

Histokrat
quelle
0

Java (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;
    });
}

Die Methoden nehmen ein Array von Zeichenfolgen und sortieren das Array an der richtigen Stelle. An der Implementierung ist nichts Besonderes zu bemerken, es werden jedoch die zu Java 8 hinzugefügten Lambda-Ausdrücke verwendet.

Ypnypn
quelle
0

Javascript (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]))

Grenze

Frequenzwerte bis 1000000000: Zum Sortieren werden die Frequenzwerte in einer großen, gepolsterten Zeichenfolge zusammengeführt

Ungolfed

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
)

Sidenote- X-~ Inkrement um 1, auch wenn die ursprüngliche Nummer X undefiniert oder NaN ist

Verwendung

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

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

edc65
quelle