Erstellung der größtmöglichen Anzahl durch Neuanordnung einer Liste

Sagen, ich habe eine Reihe von positiven ganzen Ganzzahlen; Ich möchte die Bestellung manipulieren, damit die Verknüpfung des resultierenden Arrays die größte Zahl ist. Zum Beispiel [97, 9, 13] ergibt sich 99713 ; [9,1,95,17,5] Ergebnisse in 9955171 . Ich bin mir nicht sicher.

  • Was ist der richtige Weg, um im iPython Notebook zu debuggen?
  • Scrollbar auf Matplotlib Seite anzeigen
  • Python Cmd / Powershell Fehler "Traceback (letzter Anruf zuletzt)"
  • Pydev debugger: nicht in der Lage, echte Location für Python 2.7 nach OS 10.8 Upgrade zu finden
  • Unerwartete Nummer beim Lesen der SPS mit Pymodbus
  • Anaconda Python 32-Bit versucht, Anaconda 64-Bit-Bibliotheken zu laden
  • Pythonverschlüsse
  • Beautifulsoup Ausnahmeliste außerhalb der Reichweite
  • 8 Solutions collect form web for “Erstellung der größtmöglichen Anzahl durch Neuanordnung einer Liste”

    sorted(x, cmp=lambda a, b: -1 if str(b)+str(a) < str(a)+str(b) else 1)

    Intuitiv können wir sehen, dass eine umgekehrte Art von einstelligen Zahlen zu der höchsten Zahl führen würde:

     >>> ''.join(sorted(['1', '5', '2', '9'], reverse=True)) '9521' 

    So umgekehrte Sortierung sollte funktionieren. Das Problem entsteht, wenn es mehrere stellige Snippets im Eingang gibt. Hier kann die Intuition noch 9 vor 95 und 17 vor 1 bestellen, aber warum funktioniert das? Wieder, wenn sie die gleiche Länge gewesen wären, wäre es klar gewesen, wie man sie sortiert hat:

     95 < 99 96 < 97 14 < 17 

    Der Trick ist dann, "kürzere Zahlen" zu verlängern, damit sie mit den längeren verglichen werden können und automatisch sortiert werden können, lexikographisch. Alles was Sie tun müssen, ist wirklich, um das Snippet über die maximale Länge zu wiederholen :

    • Vergleich von 9 und 95 : Vergleich 999 und 9595 statt und damit 999 kommt zuerst.
    • Vergleich von 1 und 17 : Vergleich 111 und 1717 statt und damit 1717 kommt zuerst.
    • Vergleich von 132 und 13 : vergleichen 132132 und 1313 statt und damit 132132 kommt zuerst.
    • Vergleich von 23 und 2341 : Vergleichen Sie 232323 und 23412341 stattdessen und damit 2341 kommt zuerst.

    Das funktioniert, weil Python nur die beiden Schnipsel vergleichen muss, bis sie sich irgendwo unterscheiden; Und es ist (Wiederholen) passende Präfixe, die wir überspringen müssen, wenn wir zwei Snippets vergleichen, um festzustellen, welche Reihenfolge sie benötigen, um eine größere Zahl zu bilden.

    Sie müssen nur ein Snippet wiederholen, bis es länger ist als das längste Snippet * 2 in der Eingabe, um zu garantieren, dass Sie die erste nicht passende Ziffer finden können, wenn Sie zwei Snippets vergleichen.

    Sie können dies mit einem key zu sorted() , aber Sie müssen die maximale Länge der Snippets zuerst bestimmen. Mit dieser Länge kannst du alle Snippets in der Sortierschlüssel "pad", bis sie länger als die maximale Länge sind:

     def largestpossible(snippets): snippets = [str(s) for s in snippets] mlen = max(len(s) for s in snippets) * 2 # double the length of the longest snippet return ''.join(sorted(snippets, reverse=True, key=lambda s: s*(mlen//len(s)+1))) 

    Wo s*(mlen//len(s)+1) pads das snippet mit sich selbst mehr als mlen in der Länge sein.

    Das gibt:

     >>> combos = { ... '12012011': [1201, 120, 1], ... '87887': [87, 878], ... '99713': [97, 9, 13], ... '9955171': [9, 1, 95, 17, 5], ... '99799713': [97, 9, 13, 979], ... '10100': [100, 10], ... '13213': [13, 132], ... '8788717': [87, 17, 878], ... '93621221': [936, 21, 212], ... '11101110': [1, 1101, 110], ... } >>> def test(f): ... for k,v in combos.items(): ... print '{} -> {} ({})'.format(v, f(v), 'correct' if f(v) == k else 'incorrect, should be {}'.format(k)) ... >>> test(largestpossible) [97, 9, 13] -> 99713 (correct) [1, 1101, 110] -> 11101110 (correct) [936, 21, 212] -> 93621221 (correct) [13, 132] -> 13213 (correct) [97, 9, 13, 979] -> 99799713 (correct) [87, 878] -> 87887 (correct) [1201, 120, 1] -> 12012011 (correct) [100, 10] -> 10100 (correct) [9, 1, 95, 17, 5] -> 9955171 (correct) [87, 17, 878] -> 8788717 (correct) 

    Beachten Sie, dass diese Lösung a) 3 Zeilen kurz ist und b) auch auf Python 3 arbeitet, ohne auf functools.cmp_to_key() und c) zurückgreifen zu müssen, functools.cmp_to_key() die Lösung nicht (was die Option itertools.permutations tut).

    Hinweis: Sie verketten Strings, nicht ganze Zahlen. itertools.permutations() zwei: itertools.permutations() .

     import itertools nums = ["9", "97", "13"] m = max(("".join(p) for p in itertools.permutations(nums)), key = int) 

    Sie können itertools.permutations wie angedeutet verwenden und verwenden Sie das Schlüsselargument der max-Funktion (die besagt, welche Funktion für jedes Element gelten soll, um das Maximum zu bestimmen), nachdem Sie sie mit der Join-Funktion zusammengestellt haben.

    Es ist einfacher, mit Strings zu arbeiten, um mit zu beginnen.

    Ich mag nicht die Brute-Force-Annäherung dazu. Es erfordert eine massive Berechnungsmenge für große Sätze.

    Sie können Ihre eigene Vergleichsfunktion für die sortierte builtin-Methode schreiben, die einen Sortierparameter für jedes Paar zurückgibt, basierend auf einer beliebigen Logik, die Sie in die Funktion setzen.

    Beispielcode:

     def compareInts(a,b): # create string representations sa = str(a) sb = str(b) # compare character by character, left to right # up to first inequality # if you hit the end of one str before the other, # and all is equal up til then, continue to next step for i in xrange(min(len(sa), len(sb))): if sa[i] > sb[i]: return 1 elif sa[i] < sb[i]: return -1 # if we got here, they are both identical up to the length of the shorter # one. # this means we need to compare the shorter number again to the # remainder of the longer # at this point we need to know which is shorter if len(sa) > len(sb): # sa is longer, so slice it return compareInts(sa[len(sb):], sb) elif len(sa) < len(sb): # sb is longer, slice it return compareInts(sa, sb[len(sa):]) else: # both are the same length, and therefore equal, return 0 return 0 def NumberFromList(numlist): return int(''.join('{}'.format(n) for n in numlist)) nums = [97, 9, 13, 979] sortednums = sorted(nums, cmp = compareInts, reverse = True) print nums # [97, 9, 13, 979] print sortednums # [9, 979, 97, 13] print NumberFromList(sortednums) # 99799713 

    Nun, da ist immer die rohe Kraft …

     from itertools import permutations lst = [9, 1, 95, 17, 5] max(int(''.join(str(x) for x in y)) for y in permutations(lst)) => 9955171 

    Oder dies, eine Anpassung von @ Zah's Antwort, die eine Liste von ganzen Zahlen erhält und eine Ganzzahl zurückgibt, wie in der Frage angegeben:

     int(max((''.join(y) for y in permutations(str(x) for x in lst)), key=int)) => 9955171 

    Du kannst das mit einer klugen Sortierung machen.

    Wenn zwei Strings die gleiche Länge haben, wählen Sie die größeren der beiden, um zuerst zu kommen. Einfach.

    Wenn sie nicht die gleiche Länge sind, herauszufinden, was wäre das Ergebnis, wenn die bestmögliche Kombination an die kürzere angehängt wurde. Da alles, was dem kürzeren folgt, gleich oder kleiner sein muss, kann man dies bestimmen, indem man das kurze an sich anhängt, bis es die gleiche Größe hat wie das längere. Sobald sie die gleiche Länge sind, machen Sie einen direkten Vergleich wie zuvor.

    Wenn der zweite Vergleich gleich ist, hast du bewiesen, dass die kürzere Saite nicht besser sein kann als die längere. Je nachdem, was es mit ihm gepaart hat, könnte es noch schlimmer kommen, also das längere sollte zuerst kommen.

     def compare(s1, s2): if len(s1) == len(s2): return -1 if s1 > s2 else int(s2 > s1) s1x, s2x = s1, s2 m = max(len(s1), len(s2)) while len(s1x) < m: s1x = s1x + s1 s1x = s1x[:m] while len(s2x) < m: s2x = s2x + s2 s2x = s2x[:m] return -1 if s1x > s2x or (s1x == s2x and len(s1) > len(s2)) else 1 def solve_puzzle(seq): return ''.join(sorted([str(x) for x in seq], cmp=compare)) >>> solve_puzzle([9, 1, 95, 17, 5]) '9955171' >>> solve_puzzle([97, 9, 13]) '99713' >>> solve_puzzle([936, 21, 212]) '93621221' >>> solve_puzzle([87, 17, 878]) '8788717' >>> solve_puzzle([97, 9, 13, 979]) '99799713' 

    Dies sollte viel effizienter sein, als durch alle Permutationen zu laufen.

     import itertools def largestInt(a): b = list(itertools.permutations(a)) c = [] x = "" for i in xrange(len(b)): c.append(x.join(map(str, b[i]))) return max(c) 
    Python ist die beste Programmiersprache der Welt.