• 深信服笔试--递归用法


    1、已知某一个字母序列,把序列中的字母按出现顺序压入一个栈,在入栈的任意过程中,允许栈中的字母出栈,求所有可能的出栈顺序
    思路:
    遍历序列中的每一个字母,先把当前字母入栈,这个时候,栈中肯定有字母,你可以选择继续遍历序列,也可以在这个时候把栈中的字母一个一个出栈,
    最后,遍历完序列后,再把栈中的所有字母顺序出栈,这样子就可以得到所有合法的序列;
     1 #import itertools
     2 def GetAllSeq(input, i, stk, tmp, res):
     3     tmp1 = list(tmp) # 注意tmp1和stk是要回溯的,所以这两者不能传引用;而res是一直保留结果的,传引用就对
     4     stk1 = list(stk)
     5     if i == len(input): # 结果记录
     6         stk1 = stk1[::-1]
     7         tmp1.extend(stk1)
     8         res.append(tmp1)
     9         #print(res)
    10         return
    11     stk1.append(input[i]) # 先将当前字母入栈,然后后面选择继续递归入栈或者出栈
    12     GetAllSeq(input, i+1, stk1, tmp1, res) #继续遍历
    13     while stk1: # 一个个出栈
    14         #tmp = []
    15         tmp1.append(stk1[-1])
    16         stk1.pop()
    17         GetAllSeq(input, i+1, stk1, tmp1, res)
    18 
    19 
    20 
    21 input = 'abc'
    22 res = []
    23 stk = ''
    24 tmp = ''
    25 GetAllSeq(input, 0, stk, tmp, res)
    26 
    27 res = [''.join(x) for x in res]
    28 # 法一
    29 # res = list(set(res))
    30 # res.sort()
    31 
    32 # 法二
    33 #res = itertools.groupby(res)
    34 
    35 # 法三 dict去重并保留顺序
    36 # res = list(dict.fromkeys(res))
    37 # print(res)

    2、函数match检查字符串str是否匹配模板pattern,匹配则返回0,否则返回-1。模板支持普通字符(a-z0-9A-Z)及通配符?和*。普通字符匹配该字符本身,?匹配任意一个字符,*匹配任意多个任意字符。

    思路:使用递归回溯遍历所有的情况

    def match(str, pattern):
        str_len, pattern_len = len(str), len(pattern)
        if not str_len and not pattern_len:
            return 0
        if not str_len or not pattern_len:
            return -1
        if pattern[0] == '*': #如果是*则前者递归k个单位(k进行迭代遍历取值),后者递归一个单位
            for i in range(len(str)):
                if match(str[i+1:], pattern[1:]) == 0: # 递归
                    return 0
            return -1
        elif pattern[0] == '?': # 如果是?则两者都递归一个单位
            return match(str[1:], pattern[1:])
        else:
            if pattern[0] == str[0]: # 如果是相同则两者都递归一个单位
                return match(str[1:], pattern[1:])
            else:
                return -1
    
    str = input()
    pattern = input()
    res = match(str, pattern)
    print(res)
    
    if res == 0:
        print('match')
    elif res == -1:
        print('unmat

    3、有K种颜色的小球(K<=10),每种小球有若干个,总数小于100个。

    现在有一个小盒子,能放N个小球(N<=8),现在要从这些小球里挑出N个小球,放满盒子。
    想知道有哪些挑选方式。注:每种颜色的小球之间没有差别。

    请按数字递增顺序输出挑选小球的所有方式。

    如有3种颜色,每种颜色小球的个数分别为a:1,b:2,c:3,挑出3个小球的挑法有:
    003,012,021,102,111,120

    思路:递归回溯,my_dic, res, s都可变,s用来保存理想结果,注意s的现场恢复

    # K, N = list(map(int, input().split()))
    # def bfs(i, my_dic, cnt, res, s):
    #     if i == K and cnt == N:
    #         res.append(''.join(s))
    #     elif i < K:
    #         for use in range(my_dic[i]+1): # 迭代递归:先迭代整个串,然后再递归每个子集
    #             if use <= N - cnt:
    #                 s.append(str(use))
    #                 bfs(i+1, my_dic, cnt+use, res, s)
    #                 s.pop() #回溯
    #             else:
    #                 break
    # my_dic = {}
    # for i in range(K):
    #     my_dic[i] = int(input())
    # res = []
    # bfs(0, my_dic, 0, res, [])
    # for r in res:
    #     print(r)
    
    a = [0] * 11
    ans = [0] * 11
    def Print(k, ans):
        res = ''
        for i in range(k):
            res += str(ans[i])
        print(res)
    
    def fun(i, n):
        if n == 0:
            Print(k, ans)
            return
        if n < 0 or k == i:
            return
        for j in range(a[i]+1):
            ans[i] = j
            fun(i+1, n-j)
        ans[i] = 0 #回溯
    
    k,n = list(map(int, input().split()))
    a = {}
    for i in range(k):
        a[i] = int(input())
    fun(0, n)

    4、判断所给的字符串是否由所给的词典中的若干个词组成。

    如已知词典["code", "sangfor", "org"]
    则字符串"codesangfororg" 由上述词典组成,
    字符串"codesangforsangfororg" 也由上述词典组成,
    但字符串"sangforcom" 则不由上述词典组成。

    def wordbreak(s, WordDict):
        if not s or not len(s):
            return False
        dp = [False for i in range(len(s)+1)]
        dp[0] = True
        for i in range(1, len(s)+1): # 迭代递归:先迭代遍历整个串,然后再对每个子串进行递归遍历
            for j in range(i): 
                if dp[j] and (s[j:i] in WordDict):
                    dp[i] = True
                    break
        return dp[len(s)]
    
    K = int(input())
    WordDict = []
    for i in range(K):
        WordDict.append(input())
    s = input()
    
    res = wordbreak(s, WordDict)
    print(res)

    5、总结

    先看问题是否是求整体字符串中的可变长子集(起始点不确定),如果是则先迭代遍历整个串,然后在递归每个子串,如3、4题;

    如果是起始点确定的可变长子集,如2题,则可以不用迭代遍历整个串,只需要递归遍历子串就行。

  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/hotsnow/p/12856239.html
Copyright © 2020-2023  润新知