Seite 1 von 1
String mischen
Verfasst: Montag 29. August 2011, 10:23
von Jochen1980
Servus,
wie gehe ich geschickt vor, wenn meine Funktion einen String erhält, ich dann zweimal zwischen 0 und range(len(meineingangsstring)) würfeln will und dann die beiden Zeichen im String tauschen möchte?
Danke vorab.
Re: String mischen
Verfasst: Montag 29. August 2011, 11:00
von derdon
Hab nur eine unschöne Lösung zu bieten
Code: Alles auswählen
>>> from string import ascii_lowercase
>>> import random
>>> a, b = random.sample(xrange(0, len(ascii_lowercase)), 2)
>>> a
15
>>> b
7
>>> a, b = a if a < b else b, b if b > a else a
>>> a
7
>>> b
15
>>> ascii_lowercase = ascii_lowercase[:a] + ascii_lowercase[b] + ascii_lowercase[a+1:b] + ascii_lowercase[a] + ascii_lowercase[b+1:]
>>> ascii_lowercase
'abcdefgpijklmnohqrstuvwxyz'
Re: String mischen
Verfasst: Montag 29. August 2011, 11:01
von Jochen1980
Sodala, das ist mal meine Lösung - scheint zu klappen, aber da dies auch fix laufen soll, bitte ich um Verbesserungen.
Code: Alles auswählen
def randomize_string(string_to_randomize, factor_of_shuffling):
number_of_chars = len( string_to_randomize)
number_of_shuffles = factor_of_shuffling * number_of_chars
# strings sind unveraenderbar, daher lieber string in liste wandeln
list_of_chars = list(string_to_randomize)
#print( "String:", string_to_randomize, "Liste:", list_of_chars)
for i in range(number_of_shuffles):
#print("Run:", i )
first_random = random.randint(0, (number_of_chars - 1))
second_random = random.randint(0, (number_of_chars - 1))
#print( "... Zufallszahlen:", first_random, second_random )
first_pick = list_of_chars[first_random]
second_pick = list_of_chars[second_random]
list_of_chars[first_random] = second_pick
list_of_chars[second_random] = first_pick
randomized_string = ''.join( list_of_chars )
#print("Randomisierter String:", randomized_string)
return randomized_string
Re: String mischen
Verfasst: Montag 29. August 2011, 12:02
von pillmuncher
Ich würde es so machen (Python 3.x):
Code: Alles auswählen
import random
def chunkwise(t, size=2):
return zip(*[iter(t)]*size)
def randomswaps(iterable, n=1):
result = list(iterable)
for a, b in chunkwise(random.sample(range(len(result)), n * 2)):
result[a], result[b] = result[b], result[a]
return result
for i in range(3):
print(''.join(randomswaps('pillmuncher', 3)))
Ergebnis:
Re: String mischen
Verfasst: Montag 29. August 2011, 16:31
von gkuhl
Folgendes sollte es eigentlich auch tun:
Code: Alles auswählen
def swap(iterable, n=1):
result = list(iterable)
for i in xrange(n):
i,j = (random.randint(0, len(result)) for _ in range(2))
result[i], result[j] = result[j], result[i]
return ''.join(result)
Grüße
Gerrit
Re: String mischen
Verfasst: Montag 29. August 2011, 17:45
von pillmuncher
@gkuhl: Bei deiner Lösung kann es aber passieren, dass i == j ist, und somit gar nichts vertauscht wird. Außerdem kann verschiedenes anderes passieren, so zB. wenn i und j dieselben oder umgekehrten Werte haben wie beim Schleifendurchlauf zuvor, dann wird zwar vertauscht, aber eben gleich danach wieder zurüsckgetauscht. Oder es kann passieren, das erst zB. die Buchstaben mit den Indizes 3 und 5, und danach die mit den Indizes 5 und 4 vertauscht werden. Gilt das dann immer noch als zwei Vertauschungen, wenn nicht vier, sondern nur drei Buchstaben die Plätze gewechselt haben? Aus der Nachricht des OPs geht nicht hervor, ob das erlaubt sein soll, oder nicht. Deswegen habe ich in meiner Lösung den strengeren Ansatz gewählt, der auf jeden Fall gültig ist.
Gruß,
Mick.
Re: String mischen
Verfasst: Montag 29. August 2011, 18:18
von gkuhl
@pillmuncher: Dein strengerer Ansatz macht aus Sicht der Performance sicherlich Sinn. Allerdings gehe ich immer davon aus, dass alles, was nicht explizit verboten wird, möglich sein sollte. Ich hatte am Anfang auch überlegt "sample" zu benutzen mich dann aber, gerade weil z.B. i==j möglich sein sollte, dagegen entschieden.
Grüße
Gerrit
Re: String mischen
Verfasst: Dienstag 30. August 2011, 21:06
von bords0
pillmuncher hat geschrieben:@gkuhl: Bei deiner Lösung kann es aber passieren, dass i == j ist, und somit gar nichts vertauscht wird. Außerdem kann verschiedenes anderes passieren, so zB. wenn i und j dieselben oder umgekehrten Werte haben wie beim Schleifendurchlauf zuvor, dann wird zwar vertauscht, aber eben gleich danach wieder zurüsckgetauscht. Oder es kann passieren, das erst zB. die Buchstaben mit den Indizes 3 und 5, und danach die mit den Indizes 5 und 4 vertauscht werden. Gilt das dann immer noch als zwei Vertauschungen, wenn nicht vier, sondern nur drei Buchstaben die Plätze gewechselt haben? Aus der Nachricht des OPs geht nicht hervor, ob das erlaubt sein soll, oder nicht. Deswegen habe ich in meiner Lösung den strengeren Ansatz gewählt, der auf jeden Fall gültig ist.
Doch, aus der Nachricht des OP, in der überhaupt erst Mehrfachvertauschungen erwähnt werden, geht es schon hervor. Ist alles erlaubt.