首页 新闻 搜索 专区 学院

[python]请问如何实现递归算法?

0
悬赏园豆:20 [已解决问题] 解决于 2018-10-18 10:24

可能因为我把代码贴上来所以大家觉得内容太长就懒得看了。
其实我想问的是很单纯的问题,就是如何递归实现分割字符串,我把问题简化一下吧。
有一个字符串
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]))
芽衣的主页 芽衣 | 菜鸟二级 | 园豆:380
提问于:2018-10-17 19:03
< >
分享
最佳答案
0

递归实现的思路:
1.找到你程序的终止条件。
2.倘若不符合终止条件,则函数会调用自身。

假设现在有一个函数fenge(str,a),此处的a代表特殊符号,str为你的初始字符串
基于你的题目:
你的终止条件应该是当特殊符号不存在时,则直接return得到的数组。
否则:则将return fenge(新的str,a),也就是执行过经过处理的str,a为你条件中的符号。

收获园豆:20
你风致 | 老鸟四级 |园豆:2180 | 2018-10-18 09:25

您好!谢谢您的热心指点!
按照您提供的递归思路,我编写了下面的代码,但这个代码执行到'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))
芽衣 | 园豆:380 (菜鸟二级) | 2018-10-18 09:58

@芽衣: else里面,a=a+1后,直接str_o = str_o.join("");
然后return fenge(str_o,a)

你风致 | 园豆:2180 (老鸟四级) | 2018-10-18 10:03

@心悠魂然:
您好!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
芽衣 | 园豆:380 (菜鸟二级) | 2018-10-18 10:11

@芽衣: 哦哦哦,我js写多了,python是str_o = "".join(str_o);
for循环后面的不用了

你风致 | 园豆:2180 (老鸟四级) | 2018-10-18 10:17

@心悠魂然:
谢谢您的热心回答!运行出了想要的结果。
喔...你怎么这么聪明...!
最后的代码:

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))
芽衣 | 园豆:380 (菜鸟二级) | 2018-10-18 10:23

@芽衣: hahahaha,谢谢

你风致 | 园豆:2180 (老鸟四级) | 2018-10-18 10:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册