Python中的生成器在八皇后問題上的應用

2021-06-22 13:38:44 字數 1362 閱讀 9688

八皇后問題是乙個經典的問題:

為了保證各個皇后的安全,在乙個8x8的矩陣上,必須保證任意兩個皇后不能處於同一行、同一列以及同一條對角線上,那麼安全的擺法總共有多少種呢?

好,一步步來。老話說得好,程式=資料結構+演算法。我們先來選乙個合適的資料結構。很明顯,問題中提到了矩陣,那麼二維陣列肯定是可以的,但用二維陣列是不是有點牛刀殺雞的感覺?想想,8x8的矩陣我們最終只會儲存8個元素,還有56個空間被浪費了。再看一下問題的條件:元素不能處於同一行,也就是每一行我們只會儲存乙個元素,即:f(x)=pos,x表示行號,pos表示皇后在x行的安全位置(也就是列號),而x又是連續的(1,2,3,...,8),所以說,針對這個問題,一維陣列足矣:陣列下標表示行號,對應值來表示位置。

好了,資料結構有了,想想演算法怎麼去實現。

皇后肯定是乙個個的試探性的去放,如果暫時安全就放在當前位置,不安全就換乙個位置試試,如果這一行都沒有合適的位置,那就回到前一行,讓前一行的皇后換個安全的位置,再到下一行繼續試。

ok,不用多說了,典型的回溯。我們用遞迴來實現。

不借助迭代器,**如下:

def poschk(pos,positions,n):

t1=not pos in positions

t2=true

tmpx=len(positions)-1

tmpy=pos-1

while tmpx>=0 and tmpy>=0:

if positions[tmpx]==tmpy:

t2=false

break

tmpx-=1

tmpy-=1

t3=true

tmpx=len(positions)-1

tmpy=pos+1

while tmpx>=0 and tmpy上面的**基本符合要求,至少所有的排列方式都能列印出來了,那麼如果不想列印,而是把結果存起來呢?那就在queen函式裡再加乙個list引數?這樣可行,但是不是有點彆扭,因為這個引數在queen的絕大數呼叫中都是沒用的,只有最後才會用來裝一下結果。

好,看看python的迭代器是怎麼解決這個問題的。**如下(除queen函式以外其他地方不變)

def queen(positions,num):

for pos in range(num):

t=poschk(pos,positions,num)

if t and len(positions)==num-1:

yield (pos,)

if t and len(positions)這樣的話,針對排列結果就好處理多了。

比如看看有多少種排列方式:

print len(list(queen(positions,num))) //92

python 生成器作用 Python生成器

生成器介紹 在函式內部包含yield關鍵字,那麼該函式執行的結果是生成器,生成器就是迭代器。生成器的功能 把函式結果做成迭代器 以一種優雅的方式封裝好iter,next 提供了一種自己定義迭代器的方式。使用生成器建立乙個迭代器 def a print a yield 11 使用yield,執行後返回...

python生成器好處 Python生成器筆記

python中三大器有迭代器,生成器,裝飾器,本文主要講述生成器。主要從生成器的概念,本質,以及yield關鍵字的使用執行過程。本質 生成器是一類特殊的迭代器,使用了yield關鍵字的函式不再是函式,而是生成器。使用了yield的函式就是生成器 1.yield關鍵字有兩點作用 1.1 yield語句...

python生成器函式 Python 生成器函式

一 生成器 生成器指的是生成器物件,可由生成器表示式得到,也可使用 yield 關鍵字得到乙個生成器函式,呼叫這個函式得到乙個生成器物件 生成器物件,是乙個可迭代物件,是乙個迭代器 生成器物件,是延遲計算 惰性求值的 1.1 生成器函式 函式體重包含 yield 語句的函式,就是生成器函式,呼叫後返...