题目:给定一个字符串判断是否存在环,字符串表示图的有向边,比如:’{(B->C),(->B),(C->A)}’
知识储备(拓扑排序)
百度百科:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
简单来说,依次删除图中入度为 0 的结点,如果最后能输出所有结点,这个结点序列就是拓扑排序。(不能再删除却还有入度为 0 的结点,说明该图中存在环)
代码实现
graph_string = '{(B->C),(->B),(C->A)}'
def graph_circle_checker(graph_string):
import re
input_data = list(re.findall('(\([a-zA-Z0-9]+->[a-zA-Z0-9]+\))+', graph_string))
res_input_data = list(re.findall('(\([a-zA-Z0-9]*->[a-zA-Z0-9]*\))+', graph_string))
if len(input_data) != len(res_input_data):
return -1
node_i = {}
node_o = {}
for i in range(len(input_data)):
# pos is a list have one element
pos = [m.start() for m in re.finditer('->', input_data[i])]
if input_data[i][1:pos[0]] not in node_o.keys():
node_o[input_data[i][1:pos[0]]] = 1
else:
node_o[input_data[i][1:pos[0]]] += 1
if input_data[i][pos[0]+2:-1] not in node_i.keys():
node_i[input_data[i][pos[0]+2:-1]] = 1
else:
node_i[input_data[i][pos[0]+2:-1]] += 1
while(1):
flag = 0
for i in range(len(input_data)):
pos = [m.start() for m in re.finditer('->', input_data[i])]
key_1 = input_data[i][1:pos[0]]
key_2 = input_data[i][pos[0]+2:-1]
if (key_1 not in node_i.keys() or node_i[key_1] == 0) and node_o[key_1] != 0:
node_i[key_2] -= 1
node_o[key_1] = 0
flag = 1
if flag == 0:
break
if any(node_i.values()):
return 1
else:
return 0
print(graph_circle_checker(graph_string))