Dies ist eine Lösung, kein Algorithmus :) Der Algorithmus ist in der Implementierung von itertools.combinations
begraben (aber siehe unten) für eine Implementierung ohne eingebaute Bibliotheksfunktionen).
from functools import reduce
from itertools import combinations
def assign(v, p):
v[p[0]] = p[1]
return v
def interp(word, letter, size):
return (''.join(reduce(assign, zip(comb, word), [letter] * size))
for comb in combinations(range(size), len(word)))
Beispiel (Punkte anstelle von Leerzeichen verwenden, damit sie besser sichtbar):
>>> print('\n'.join(interp("cats", ".", 6)))
cats..
cat.s.
cat..s
ca.ts.
ca.t.s
ca..ts
c.ats.
c.at.s
c.a.ts
c..ats
.cats.
.cat.s
.ca.ts
.c.ats
..cats
Es ist eigentlich ziemlich einfach combinations
zu implementieren (aber warum die Mühe, da es bereits definiert ist?). Hier ist eine Lösung, die funktioniert viel zu viel Tupel Verkettung effizient zu sein, sondern zeigt den Algorithmus:
def combs(vec, count, start=0):
if count == 0:
yield()
else:
for i in range(start, len(vec) + 1 - count):
for c in combs(vec, count - 1, i + 1):
yield((i,) + c)
Mit anderen Worten, für jede mögliche erste Position, wählen Sie das und vervollständigen die Kombination mit den übrigen Positionen. Ebenso können Sie direkt die gewünschte Funktion implementieren:
def interp(word, letter, size):
if len(word) == 0:
yield letter * size
else:
for i in range(size + 1 - len(word)):
for comb in interp(word[1:], letter, size - i - 1):
yield letter * i + word[0] + comb
Ich zögere, dies zu verbessern, weil es so dicht ist, aber die Frage hat nach einer Implementierung gefragt, so. – Blender
@blender: Wenn ich mehr Zeit hätte, könnte ich es spärlicher machen :) – rici
hm, auch nachdem ich das für ca. 5 Minuten angeschaut habe weiß ich immer noch nicht ob ich eine identische Antwort gepostet habe oder ob sie sich unterscheiden :) Aber das tun sie zumindest ähnlich aussehen. – MSeifert