zoukankan      html  css  js  c++  java
  • 深信服笔试--递归用法

    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题,则可以不用迭代遍历整个串,只需要递归遍历子串就行。

  • 相关阅读:
    233
    膝为筋之府
    AES 可逆性加密算法
    DES 可逆性加密算法
    Java Swing如何让窗体居中显示
    eclipse 安装插件
    eclipse 搭建Swt 环境
    Java Set元素比较
    Greenplum数据库中系统表gp_ distribution_ policy详解
    Greenplum数据库中系统表pg_class详解
  • 原文地址:https://www.cnblogs.com/hotsnow/p/12856239.html
Copyright © 2011-2022 走看看