我不确定您的代码要做什么。您的with
语句打开一个文件,但您所做的只是将文件对象附加到with
结束前的列表中,然后它被关闭(不读取其内容)。我怀疑他不是你想要的,但我不确定你的目标是什么。
如果我正确理解您的问题,您正在尝试计算图形的连接分量。在这种情况下,图形的顶点是“#”字符,而边是这些字符在任何方向(水平、垂直或对角线)上彼此相邻的位置。
有非常简单的算法可以解决这个问题。一种是使用不相交的集合数据结构(也称为“联合查找”结构,因为union
和find
是它支持的两个操作)'#'
在从文件中读取字符组时将它们连接在一起。
这是我不久前为回答另一个问题而写的一个相当小的不相交集:
class UnionFind:
def __init__(self):
self.rank = {}
self.parent = {}
def find(self, element):
if element not in self.parent: # leader elements are not in `parent` dict
return element
leader = self.find(self.parent[element]) # search recursively
self.parent[element] = leader # compress path by saving leader as parent
return leader
def union(self, leader1, leader2):
rank1 = self.rank.get(leader1,1)
rank2 = self.rank.get(leader2,1)
if rank1 > rank2: # union by rank
self.parent[leader2] = leader1
elif rank2 > rank1:
self.parent[leader1] = leader2
else: # ranks are equal
self.parent[leader2] = leader1 # favor leader1 arbitrarily
self.rank[leader1] = rank1+1 # increment rank
以下是如何将它用于您的问题,x, y
为节点使用元组:
nodes = set()
groups = UnionFind()
with open('file.txt') as f:
for y, line in enumerate(f): # iterate over lines
for x, char in enumerate(line): # and characters within a line
if char == '#':
nodes.add((x, y)) # maintain a set of node coordinates
# check for neighbors that have already been read
neighbors = [(x-1, y-1), # up-left
(x, y-1), # up
(x+1, y-1), # up-right
(x-1, y)] # left
for neighbor in neighbors:
if neighbor in nodes:
my_group = groups.find((x, y))
neighbor_group = groups.find(neighbor)
if my_group != neighbor_group:
groups.union(my_group, neighbor_group)
# finally, count the number of unique groups
number_of_groups = len(set(groups.find(n) for n in nodes))