簡體   English   中英

Python中的地圖顏色算法

[英]Map Color Algorithm in Python

我在Python(3.2版)中有一個2D數組,如下所示:

...AAA....
...AAABB..
..BBBBBCC.
.....CCCC.
.DDD..CC..
.DDD......

它代表一種地圖,其區域塗有不同的顏色。 上面的示例顯示了四個不同的區域A,B,C和D。

這是為數組建立索引的示例:map [1] [5] =='A'將返回True。

我正在嘗試編寫一個函數,該函數接受這樣的數組和行/列索引,並返回具有相同“顏色”的相鄰空格的數量。 因此,使用上面的示例,這里有一些返回值(參數分別是數組,行和列號:

6 <-- countArea(map, 5, 2)
8 <-- countArea(map, 2, 8)

我想將其實現為遞歸函數,但我無法弄清楚。 這是我到目前為止的內容:

def countArea(map, row, col):

    key = map[row][col]

    if (map[row-1][col] == key):
        return 1 + countArea(map, row-1, col)
    elif (map[row+1][col] == key):
        return 1 + countArea(map, row+1, col)
    elif (map[row][col+1] == key):
        return 1 + countArea(map, row, col+1)
    elif (map[row][col-1] == key):
        return 1 + countArea(map, row, col-1)
    else:
        return 1

我知道我在這里缺少一些基本知識。 我基本上是說“這是當前字符,現在從各個方向看一下它是否具有相同的字符。”

我的問題是,在此遞歸定義中我缺少什么?

謝謝你的幫助。

我的問題是,在此遞歸定義中我缺少什么?

一旦對網格平方進行了計數,就不能再次對其進行計數(這包括通過對countArea()的遞歸調用進行計數!)

您當前的算法會盡可能向北移動,然后繼續向南走一步,然后向北走一步。 重復執行此兩步序列,直到堆棧空間用完。

如果願意,您可以在Wikipedia上閱讀有關此問題的算法。

在您的代碼中,算法將在給定輸入字段的左側查找一個字段,而在遞歸調用中,算法將再次在初始字段上調用該函數。 (您顯然不想要什么,因為它會導致無限遞歸)

方法1

在仍然使用遞歸的情況下克服此問題的一種方法是指定一個方向 ,在該方向上遞歸應查找更多相同類型的字段。 例如,對第一個字段正北(或上方 )的調用可能會遞歸地看起來更北或向東(或向右 ),向東的字段向南( 朝下 )和向東,依此類推。

通過明智地選擇第一步,您可以確保在掃描區域中沒有重疊。 但是,它需要一些調整以指定遞歸調用應掃描的方向。 但是:請注意,如果該區域懸空,則此算法將不起作用,因此,如果不能僅通過向右上方移動就可以到達起點東北方的每個字段。

存在更多類似這樣的算法,它們也能夠解決上述問題。 在Wikipedia上查看“ 洪水填充”

方法2

您還可以以某種方式保存已訪問的字段,如果該字段已被訪問,則可以直接從遞歸調用中返回。

以下實現應起作用:

def countArea(map, row, col, key=None, seen=None):
    if key is None:
        key = map[row][col]
    if seen is None:
        seen = set()
    seen.add((row, col))  # mark this location as visited
    n = 1
    for dy, dx in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
         r, c = row + dy, col + dx
         if r < 0 or r >= len(map) or c < 0 or c >= len(map[0]):  # check boundaries
             continue
         # only increment and recurse if key matches and we haven't already visited
         if map[r][c] == key and (r, c) not in seen:
             n += countArea(map, r, c, key, seen)
    return n

例:

>>> print '\n'.join(''.join(row) for row in map)
...AAA....
...AAABB..
..BBBBBCC.
.....CCCC.
.DDD..CC..
.DDD......
>>> countArea(map, 5, 2)
6
>>> countArea(map, 2, 8)
8

請注意,這假設只將具有相同按鍵的區域僅在對角線上觸摸,例如對於以下地圖countArea(map, 0, 0)countArea(map, 1, 1)都將返回1:

A.
.A

附帶說明一下,您不應將map用作變量名,因為它將掩蓋內置的map()函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM