可能因为我把代码贴上来所以大家觉得内容太长就懒得看了。
其实我想问的是很单纯的问题,就是如何递归实现分割字符串,我把问题简化一下吧。
有一个字符串
A1B3C2D2E
想通过递归的方法依次把这个字符串分割为
'A','B3C2D2E' #通过1分割后的结果
'A','B3C','D','E' #通过2分割后的结果
'A','B','C','D','E' #通过3分割后的结果
======下面是问题简化前的内容,如果嫌太长可以忽略========
有一个自己写的函数cutPro(),它可以实现split分割字符串的功能,split之后的字符串变成列表,列表中的每个元素又再调用cutPro(),直到不需要分割为止。
ーーーーーーーーーーーーーーーーーー
比如有字符串'A {[[B]|[C] [D] [E [F]]] G H|I}'
先分割为A和[[B]|[C] [D] [E [F]]] G H|I
再把[[B]|[C] [D] [E [F]]] G H|I分割为[[B]|[C] [D] [E [F]]] G H和I
如此这般分割到没有括号为止。
ーーーーーーーーーーーーーーーーーー
自己写了3个函数:
cutPoint():决定split的位置
rplStr():给需要split的位置做标记
cutPro():根据cutPoint()提供的位置来split字符串
ーーーーーーーーーーーーーーーーーー
这3个函数的关系如下:
def cutPro():
cutPoint()
rplStr()
ーーーーーーーーーーーーーーーーーー
下面是详细代码,现在这个代码只能分割第一层,输出结果如下:
['A', '{[[B]|[C] [D] [E [F]]] G H|I}']
如果觉得内容太长不看代码也恳请给一个思路或简单例子!请各位大神帮帮忙救救我!
#决定split的位置
def cutPoint(str_n):
verticalLine = {} #竖线的所在层级和位置
space = {} #括号+空格的所在层级和位置
hierarchy = 1 #初始层级为1
cut_v = '' #确定split竖线的位置
cut_s = '' #确定split空格的位置
for n in range(len(str_n)):
try:
#有左括号时,层级+1
if (str_n[n] == "[") | (str_n[n] == "{"):
hierarchy += 1
#有右括号时,层级-1
if (str_n[n] == "]") | (str_n[n] == "}"):
hierarchy -= 1
#有竖线时,记录竖线所在位置和所在层级
if str_n[n] == '|':
if verticalLine.setdefault(hierarchy,[n]) != [n]:
verticalLine[hierarchy].append(n)
#有括号+空格时,记录空格所在位置和所在层级
if (str_n[n] == ' ' and str_n[n + 1] == '[') or (str_n[n] == ' ' and str_n[n + 1] == '{'):
if space.setdefault(hierarchy, [n]) != [n]:
space[hierarchy].append(n)
if (str_n[n] == ']' and str_n[n + 1] == ' ') or (str_n[n] == '}' and str_n[n + 1] == ' '):
if space.setdefault(hierarchy, [n + 1]) != [n + 1]:
#如果已经记录了位置就不再重复记录
if n + 1 not in space[hierarchy]:
space[hierarchy].append(n + 1)
except:
n_err = True
n += 1
#只获取第1层级的竖线和括号+空格的位置
if 1 in verticalLine:
cut_v = verticalLine[1]
if 1 in space:
cut_s = space[1]
return cut_v,cut_s
#给需要split的位置做标记
def rplStr(text,list,replacement=''):
for i in range(len(list)):
text = '%s%s%s'%(text[:list[i]],replacement,text[list[i]+1:])
return text
def cutPro(strLst):
#决定split的位置
#cut_v:竖线的位置
#cut_s:括号+空格的位置
cut_v,cut_s = cutPoint(strLst)
#有竖线的时候按照竖线的所在位置split
if cut_v != '':
strLst = rplStr(strLst,cut_v,'●')
#有括号+空格的时候按照空格的所在位置split
elif cut_s != '':
strLst = rplStr(strLst,cut_s,'●')
strLst = strLst.split('●')
return strLst
if __name__ == "__main__":
str_n = 'A { [ [ B ] | [ C ] [ D ] [ E [ F ] ] ] G H | I }'
str_n = str_n.replace('[ ','[').replace(' ]',']').replace('{ ','{').replace(' }','}').replace(' | ','|')
strLst = [str_n]
for i in range(len(strLst)):
print(cutPro(strLst[i]))
递归实现的思路:
1.找到你程序的终止条件。
2.倘若不符合终止条件,则函数会调用自身。
假设现在有一个函数fenge(str,a),此处的a代表特殊符号,str为你的初始字符串
基于你的题目:
你的终止条件应该是当特殊符号不存在时,则直接return得到的数组。
否则:则将return fenge(新的str,a),也就是执行过经过处理的str,a为你条件中的符号。
您好!谢谢您的热心指点!
按照您提供的递归思路,我编写了下面的代码,但这个代码执行到'A'之后就return结果了,后面的'B2C1D1E'就不继续执行了...
这段代码的输出结果是:
['A']
请问要如何让它可以继续执行下去?
def fenge(str_o,a):
strLst = []
#当特殊符号不存在时,则直接return得到的数组
if ('0' not in str_o) and ('1' not in str_o) and ('2' not in str_o):
strLst.append(str_o)
return strLst
#否则将return fenge(执行过经过处理的str,条件中的符号a)
else:
str_o = str_o.split(str(a))
a = a + 1
for i in range(len(str_o)):
print(str_o[i])
return fenge(str_o[i],a)
if __name__ == "__main__":
str_o = 'A0B2C1D1E'
a = 0
print(fenge(str_o,a))
@芽衣: else里面,a=a+1后,直接str_o = str_o.join("");
然后return fenge(str_o,a)
@心悠魂然:
您好!str_o是列表,列表好像没有办法使用join。
str_o = str_o.join("");
AttributeError: 'list' object has no attribute 'join'
修改之后的代码:
def fenge(str_o,a):
strLst = []
#当特殊符号不存在时,则直接return得到的数组
if ('0' not in str_o) and ('1' not in str_o) and ('2' not in str_o):
strLst.append(str_o)
return strLst
#否则将return fenge(执行过经过处理的str,条件中的符号a)
else:
str_o = str_o.split(str(a))
a = a + 1
str_o = str_o.join("");
return fenge(str_o,a)
for i in range(len(str_o)):
print(str_o[i])
return fenge(str_o[i],a)
if __name__ == "__main__":
str_o = 'A0B2C1D1E'
a = 0
@芽衣: 哦哦哦,我js写多了,python是str_o = "".join(str_o);
for循环后面的不用了
@心悠魂然:
谢谢您的热心回答!运行出了想要的结果。
喔...你怎么这么聪明...!
最后的代码:
def fenge(str_o,a):
strLst = []
#当特殊符号不存在时,则直接return得到的数组
if ('0' not in str_o) and ('1' not in str_o) and ('2' not in str_o):
strLst.extend(str_o)
return strLst
#否则将return fenge(执行过经过处理的str,条件中的符号a)
else:
str_o = str_o.split(str(a))
a = a + 1
str_o = "".join(str_o)
return fenge(str_o,a)
if __name__ == "__main__":
str_o = 'A0B2C1D1E'
a = 0
print(fenge(str_o,a))
@芽衣: hahahaha,谢谢