เมื่อเร็ว ๆ นี้ฉันได้เขียนฟังก์ชันเพื่อสร้างลำดับบางอย่างโดยมีข้อ จำกัด ที่ไม่สำคัญ ปัญหามาพร้อมกับวิธีแก้ซ้ำตามธรรมชาติ ตอนนี้มันเกิดขึ้นว่าแม้จะมีอินพุตที่ค่อนข้างเล็ก แต่ลำดับก็มีหลายพันดังนั้นฉันจึงต้องการใช้อัลกอริทึมของฉันเป็นตัวสร้างแทนที่จะใช้มันเพื่อเติมเต็มรายการด้วยลำดับทั้งหมด
นี่คือตัวอย่าง สมมติว่าเราต้องการคำนวณการเรียงสับเปลี่ยนทั้งหมดของสตริงด้วยฟังก์ชันวนซ้ำ อัลกอริทึมไร้เดียงสาต่อไปนี้ใช้อาร์กิวเมนต์พิเศษ 'ที่เก็บข้อมูล' และต่อท้ายการเปลี่ยนแปลงเมื่อใดก็ตามที่พบ:
def getPermutations(string, storage, prefix=""):
if len(string) == 1:
storage.append(prefix + string) # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], storage, prefix+string[i])
storage = []
getPermutations("abcd", storage)
for permutation in storage: print permutation
(โปรดอย่าสนใจเกี่ยวกับความไม่มีประสิทธิภาพนี่เป็นเพียงตัวอย่างเท่านั้น)
ตอนนี้ฉันต้องการเปลี่ยนฟังก์ชั่นของฉันให้เป็นเครื่องกำเนิดไฟฟ้ากล่าวคือให้การเปลี่ยนแปลงแทนที่จะผนวกเข้ากับรายการพื้นที่เก็บข้อมูล:
def getPermutations(string, prefix=""):
if len(string) == 1:
yield prefix + string # <-----
else:
for i in range(len(string)):
getPermutations(string[:i]+string[i+1:], prefix+string[i])
for permutation in getPermutations("abcd"):
print permutation
รหัสนี้ไม่ทำงาน (ฟังก์ชั่นทำงานเหมือนตัวสร้างที่ว่างเปล่า)
ฉันพลาดอะไรไปรึเปล่า? มีวิธีเปลี่ยนอัลกอริทึมการเรียกซ้ำข้างต้นให้เป็นเครื่องกำเนิดไฟฟ้าโดยไม่ต้องแทนที่ด้วยการวนซ้ำหรือไม่?
yield from getPermutations(string[:i] + string[i+1:])
ซึ่งมีประสิทธิภาพมากกว่าในหลาย ๆ ด้าน!