編程挑戰 ----- 螺旋矩陣的實現

2018.03.11
author : wills
今天給大家分享一個我學習python語言以來自己感覺寫的最複雜的程序。當然這些全是我個人的看法與理解,如果有不足之處,大家多多指出。
螺旋矩陣,先先上一張圖給大家看看。
下面分別是5階10階24階的螺旋矩陣

5階螺旋矩陣
10階

24階

要寫出這個程序的代碼,首先我們需要找到這個螺旋矩陣裏面蘊藏的規律

5階思路

從圖上可以看出,5階的螺旋矩陣我們要打印出這個圖案需要進行5*1+4*2+3*2+2*2+1*2,共9次循環。
6階的矩陣用同樣的方法分析,需要6*1+5*2+4*2+3*2+2*2+1*2=11次循環
7階 需要 7*1+6*2+5*2+4*2+3*2+2*2+1*2 = 13次循環。
上面就是我發現的主要規律之一
我的總體思路是,首先不管要求多少階的螺旋矩陣,我先生成一個包含所有數字的列表list1=[1,2,3,4,5…..],再生成一個二階的列表list2=[[],[],….],即一個大列表套小列表。n階矩陣,就有n個小列表,小列表就有n個數字,然後利用規律一,不停地循環將list1對應的值賦給,list2中的元素,最後打印list2就得到所求矩陣。在這裏,因爲第一行剛好和list2,第一個元素相同,所以循環可以少做一次,這時再看規律一變成了
5 階:4*2+3*2+2*2+1*2 =8次 —》(2n-2)
初始循環次數: 4 —————》》 n-1
6階:5*2+4*2+3*2+2*2+1*2 = 10次 —》(2n-2)
初始循環次數: 5 —————》》 n-1
7階:6*2+5*2+4*2+3*2+2*2+1*2 = 12次 —》(2n-2)
初始循環次數: 7 —————》》 n-1
8階:7*2+6*2+5*2+4*2………..
可以看出,每循環兩次,需要循環的次數就減少了1。
然後再看每次循環的方向:
第一次循環由上往下,list2中的小列表的最後一個元素,依次被list1賦值;
第二次循環由左到右,list2中最後一個小列表的元素依次被賦值;
第三次由下到上,list2中小列表第一個元素依次被賦值;
第四次由左到右,list2中第二個小列表中的第二到倒數第二個元素依次被賦值。
第五次又變的和第一次一樣了再次構成了循環。。。
此時代碼大致構造就是這樣

def helix_matrix(n)
    # n 階矩陣,加一是爲了不取0
    list1 = [x for x in range(1,n ** 2 + 1)]
    list2 = [[y for y in range(1,n + 1] for _ in range(n)]
    suffix =n
    time = n-1
    for n in range(2*n-2):
        if n % 4 == 0:
            for i in range(time):
                ...
        elif n % 4 == 1:
            for j in range(time,0,-1):
                ...
            time -= 1
        elif n % 4 == 2:
            for k in range(time,0,-1):
                ...
        else: 
            for l in range(time) 

然後爲了區別循環層次,外層我稱爲循環1,內層我稱爲循環2
循環2每次循環後到下一輪時,list2小列表的下標都會改變,因此我們需要根據規律來,使用幾個標籤變量來使得每次循環的時候,list2的小列表下標都符合循環,最終的代碼如下,display函數只是爲了打印出來好看的。想要幾階的螺旋矩陣,只需要改變傳入參數n就可以了,sleep函數是爲了在cmd命令界面多停留一會。。。

from time import sleep
def spiral_num(n):
    numbers = [x for x in range(1, n ** 2 + 1)]
    num = [[x for x in range(1, n + 1)] for _ in range(1, n + 1)]
    suffix = n
    lieshu = n-1
    hangshu = n-1
    cishu = n-1
    bq = 1
    qb = 1
    qq = 0
    bb = 1
    for i in range(2*n-2):
        if i % 4 == 0:
            for j in range(cishu):
                num[j+bq][lieshu] = numbers[suffix]
                suffix += 1
            bq += 1
            lieshu -= 1
        elif i % 4 == 1:
            for k in range(cishu, 0, -1):
                num[hangshu][k-qb] = numbers[suffix]
                suffix += 1
            qb -= 1
            hangshu -= 1
            cishu -= 1
        elif i % 4 == 2:
            for ii in range(cishu, 0, -1):
                num[ii+qq][lieshu-cishu] = numbers[suffix]

                suffix += 1
            qq += 1
        else:
            for jj in range(cishu):
                num[hangshu-cishu+1][jj+bb] = numbers[suffix]
                suffix += 1
            bb += 1
            cishu -= 1
    return num


def display(list):
    for val in list:
        for i in range(len(val)):
            print('%03d' % val[i],end='  ')
        print()


def main():
    lis = spiral_num(5)
    display(lis)
    sleep(1000)


if __name__ == '__main__':
    main()
發佈了43 篇原創文章 · 獲贊 19 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章