1. <mark id="s2zkv"><ol id="s2zkv"></ol></mark>
      <mark id="s2zkv"></mark>

        函数练习

        1.把一个字典扁平化,源字典为{‘a‘:{‘b‘:1,‘c‘:2}, ‘d‘:{‘e‘:3,‘f‘:{‘g‘:4}}} 。

        分享图片

         

        上面字典的扁平化可以转化为下面的字典:{“a.c”:2,"d.e":3,"d.f.g":4,"a.b":1}

        source = {a:{b:1,c:2}, d:{e:3,f:{g:4}}}
        target = {}
        
        #recursion
        def flatmap(src,prefix = ""):
            for k,v in src.items():
                if isinstance(v,(list,tuple,set,dict)):
                    flatmap(v,prefix=prefix+k+".")#递归调用
                else:
                    target[prefix+k]=v
                    
        flatmap(source)
        print(target)
        
        结果为:
        
        {a.b: 1, a.c: 2, d.e: 3, d.f.g: 4}

        像一般这样的函数都会生成一个新的字典,上面的代码借用了外部的变量,破坏了函数的封装,因此可以对上面的函数稍微改造下,dest字典可以由内部来创建,当然也可以外部提供。

        source = {a:{b:1,c:2}, d:{e:3,f:{g:4}}}
        
        #recursion
        def flatmap(src,dest=None,prefix = ""):
            if dest ==None:
                dest = {}
            for k,v in src.items():
                if isinstance(v,(list,tuple,set,dict)):
                    flatmap(v,dest,prefix=prefix+k+".")#递归调用
                else:
                    dest[prefix+k]=v
            return dest
        
        print(flatmap(source))
        
        结果为:
        
        {a.b: 1, a.c: 2, d.e: 3, d.f.g: 4}

        上面的函数有一个缺点,那就是将内部的字典暴露给了外部,能否函数提供一个参数源字典,返回一个新的扁平化字典?递归的时候要把目标字典的引用传递多层,这个时候应该怎么处理?

        source = {a:{b:1,c:2}, d:{e:3,f:{g:4}}}
        
        #recursion
        def flatmap(src):
            def _flatmap(src,dest=None,prefix=""):
                for k,v in src.items():
                    key = prefix+k
                    if isinstance(v,(list,tuple,set,dict)):
                        _flatmap(v,dest,key+".")#递归调用
                    else:
                        dest[key]=v
                
            dest = {}
            _flatmap(src,dest)
            return dest
        
        print(flatmap(source))
        
        结果为:
        {a.b: 1, a.c: 2, d.e: 3, d.f.g: 4}

        2.实现base64编码,要求自己实现算法,不用库。

        分享图片

         

         将输入每3个字节断开,拿出一个3个字节,每6个bit断开成4段。2**6=64,因此有了base64的编码表。每一段当做一个8bit看它的值,这个值就是base64编码表的索引值,找到对应字符。再取出3个字节,同样处理,直到最后。

        举例:

        abc对应的ASCII码为:0x61 0x62 0x63

        01100001 01100010 01100011#abc

        011000 010110 001001 100011

        00011000 00010110 00001001 00100011 #每6位补齐为8位

        24 22 9 35

        末尾的处理?

        1. 正好3个字节,处理方式同上。
        2. 剩1个字节或2个字节,用0补满3个字节。
        3. 补0的字节用=表示。
        # 自己实现对一段字符串进行base64编码
        
        alphabet = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwsyz0123456789+/"
        
        teststr = "abcd"
        tsetstr ="Manma"
        
        def base64(src):
            ret = bytearray()
            length = len(src)
            #用r记录补0的个数
            r = 0
            for offset in range(0,length,3):
                if offset+3<=length:
                    triple = src[offset:offset+3]
                else:
                    triple = src[offset:]
                    r = 3-len(triple)
                    triple = triple +"\x00"*r#补几个0
                    
                #print(triple,r)
                #将3个字节看成一个整体转成字节bytes,大端模式
                #abc=>0x616263
                b = int.from_bytes(triple.encode(),"big")#小端模式为"little"
                print(hex(b))
                
                
                #01100001 01100010 01100011 #abc
                #011000 010110 001001 100011 #每6位断开
                
                for i in range(18,-1,-6):
                    if i==18:
                        index = b>>i
                    else:
                        index = b>>i &0x3F #0b0011 1111
                    ret.append(alphabet[index])#得到base64编码的列表
                #策略是不管是不是补0,都补满,只有最后一次可能出现补0的
                #在最后替换掉就是了,代码清晰,而且替换至多2次
                #在上一个循环中判断r!=0,效率可能会更高些
                
                for i in range(1,r+1):#1到r,补几个0替换几个=
                    ret[-i]=0x3D
            return ret
        
        print(base64(tsetstr))

        结果为:
        0x4d616e
        0x6d6100
        bytearray(b‘TWFubWE=‘)
        #base64实现 
        import base64
        print(base64.b64encode(teststr.encode()))

        结果为:
        b‘TWFubWE=‘

        练习3:求两个字符串的最长公共子串

        思考:

        s1 = "abcdefg"

        s2 = "defabcd"

        方法一:矩阵算法

        让s2的每一个元素,去分别和s1的每一个元素比较,相同为1 ,不同为0,有下面的矩阵。

        分享图片

         

         上面都是s1的索引。

        看与斜对角平行的线,这个线是穿过1的,那么最长的就是最长子串。

        print(s1[3:3+3])

        print(s1[0:0+4])最长

         

        矩阵求法还需要一个字符扫描最长子串的过程,扫描的过程就是len(s1)len(s2)次,O(nm).

        有办法一遍循环就找出最长的子串嘛?

        0001000第一行,索引为3,0。

        第二行的时候如果4,1是1,就判断3,0是否为1,为1就把3,0加1。

        第二行的时候如果5,2是1,就判断4,1是否为1,是1就加1,再就判断3,0是否为1,为1就把3,0加1 。

        分享图片

         

         上面的方法是个递归问题,不好。

        最后在矩阵中找到最大的元素,从它开始就能写出最长的子串了。

        但是这个不好算,因为是逆推的,改为顺推。

        分享图片

         

         顺推的意思,就是如果找到一个就看前一个的数字是几,然后在它的基础上加1。

        s1 = "abcdefg"
        s2 = "defabcd"
        s2 = "defabcdoabcdeftw"
        s3 = "1234a"
        s4 = "5678"
        s5 = "abcdd"
        
        def findit(str1,str2):
            matrix = []
            #从x轴或者y轴取都可以,选择x轴,xmax和xindex
            xmax = 0
            xindex = 0
            for i,x in enumerate(str2):
                matrix.append([])
                for j,y in enumerate(str1):
                    if x!=y:#若两个字符不相等
                        matrix[i].append(0)
                    else:
                        if i==0 or j ==0:#两个字符相等,有字符在边上的
                            matrix[i].append(1)
                        else:#不在边上
                            matrix[i].append(matrix[i-1][j-1]+1)
        
                        if matrix[i][j]>xmax:#判断当前加入的值和记录的最大值比较
                            xmax = matrix[i][j]#记录最大值,用于下次比较
                            xindex = j#记录当前值的x轴偏移量,和str1[xindex+1-xmax:xindex+1匹配]
                            xindex+=1#只是为了计算的需求才+1,和str1[xindex-xmax:xindex]匹配
                        
            #return str1[xindex+1-xmax:xindex+1]
            return str1[xindex - xmax:xindex]
        
        
        print(findit(s1,s2)) 
        print(findit(s1,s3))               
        print(findit(s1,s4))             
        print(findit(s1,s5))  
        
        
        s1 = " abcdefg "
        s2 = "304abcdd"
        print(findit(s1,s5))
        
        
        结果为:
        
        abcdef
        a
        
        abcd
        abcd

        方法二:

        可不可以这样思考?

        字符串都是连续的字符,所以才有了下面的思路。

        思路一:

        第一轮

        从s1中依次取1个字符,在s2中查找,看是否能够找到子串。

        如果没有一个字符在s2中找到,说明就没有公共子串,直接退出。如果找到了至少一个公共子串,则很有可能还有更长的公共子串,可以进入下一轮。

        第二轮

        然后从s1中取连续的2个字符,在s2中查找,看看能够找到公共的子串。如果没有找到,说明最大公共子串就是上一轮的随便的哪一个就行了。如果找到至少一个,则说明公共子串可能还可以再长一些。可以进入下一轮。

        改进,其实只要找到第一轮的公共子串的索引,最长公共子串也就是从它开始的,所以以后的轮次都从这些索引位置开始,可以减少比较的次数。

        思路二:

        既然是求最大子串,我先看s1全长作为子串。

        在s2中搜索,是否返回正常的index, 正常就找到了最长的子串。

        没有找到,把s1按照length-1取多个子串。

        在s2中搜索,是否能返回正常的index。

        注意:

        不要一次把s1的所有子串生成,用不了,也不要从最短开始,因为题目要最长的。

        但是也要注意,万一他们的公共子串就只有一个字符,或者很少字符的,思路一就会占优势。

        s1 = "abcdefg"
        s2 = "defaabcdoabcdeftw"
        s3 = "1234a"
        
        def findit(str1,str2):
            count = 0#看看效率,计数
            length = len(str1)
            
            for sublen in range(length,0,-1):
                for start in range(0,length - sublen +1):
                    substr = str1[start:start+sublen]
                    count+=1
                    if str2.find(substr)>-1:#found
                        print("count={},substrlen={}".format(count,sublen))
                        return substr
        print(findit(s1,s2))
        print(findit(s1,s3))
        
        结果为:
        
        count=2,substrlen=6
        abcdef
        count=22,substrlen=1
        a
        相关文章
        相关标签/搜索
        最准三码中特2020年香港六合马会开奖结果现场直播开奖历史资料记录在线查询网二四六天天好彩免费资料大全 聂荣县| 南漳县| 龙里县| 梁河县| 南丹县| 隆德县| 呼图壁县| 盘山县| 池州市| 页游| 松滋市| 巴塘县| 元氏县| 尖扎县| 大悟县| 齐齐哈尔市| 平度市| 泗阳县| 潞西市| 离岛区| 凉城县| 镶黄旗| 柞水县| 济南市| 商河县| 甘洛县| 通城县| 上杭县| 津市市| 绥德县| 华安县| 璧山县| 临湘市| 会泽县| 长春市| 化德县| 公安县| 洛宁县| 平罗县| 德惠市| 扶余县| 陇西县| 永春县| 长宁区| 延边| 耒阳市| 定西市| 兴化市| 津市市| 石家庄市| 九台市| 和顺县| 葫芦岛市| 峡江县| 平利县| 大英县| 江陵县| 安岳县| 澜沧| 鄂伦春自治旗| 西藏| 通化县| 阿鲁科尔沁旗| 闸北区| 嫩江县| 平遥县| 区。| 梁河县| 长沙县| 探索| 开平市| 屏南县| 台北县| 济宁市| 玛曲县| 邛崃市| 汕尾市| 古丈县| 长岭县| 耒阳市| 中超| 白银市| 太仆寺旗| 杭锦旗| 汝州市| 沙雅县| 宁都县| 吉首市| 青河县| 克什克腾旗| 班戈县| 韩城市| 呼伦贝尔市| 鹿邑县| 太康县| 缙云县| 盘锦市| 奇台县| 柳州市| 灵石县| 龙门县| 高阳县| 随州市| 谢通门县| 调兵山市| 洪江市| 莲花县| 渑池县| 陵川县| 习水县| 绩溪县| 南开区| 安吉县| 崇仁县| 新乡市| 上林县| 米易县| 博罗县| 石首市| 东宁县| 理塘县| 汉寿县| 开鲁县| 长寿区| 加查县| 婺源县| 庆城县| 靖州| 宁津县| 德兴市| 潜山县| 梅河口市| 廉江市| 吉安县| 邳州市| 探索| 余干县| 阜城县| 安宁市| 阳新县| 姚安县| 长顺县| 河间市| 淮北市| 轮台县| 镇雄县| 方城县| 高密市| 射阳县| 商都县| 甘德县| 余庆县| 芷江| 陇川县| 三门县| 阳新县| 蒙山县| 黑水县| 定安县| 古蔺县| 肥乡县| 通渭县| 扬州市| 乐都县| 阳山县| 中宁县| 将乐县| 江西省| 明溪县| 中江县| 华池县| 库尔勒市| 揭阳市| 雅江县| 旬阳县| 招远市| 九江市| 渭源县| 沅江市| 上虞市| 文化| 长治市| 桂东县| 马关县| 曲周县| 界首市| 宜州市| 宁安市| 宣武区| 改则县| 疏附县| 陵川县| 鞍山市| 花莲县| 肇庆市| 台北市| 芜湖县| 叶城县| 和龙市| 嘉鱼县| 康定县| 西平县| 安远县| 舞钢市| 沁水县| 深泽县| 清原| 和田市| 余姚市| 米脂县| 扎囊县| 桓台县| 巴青县| 西吉县| 无棣县| 湛江市| 新沂市| 大同市| 莎车县| 巴青县| 聊城市| 德惠市| 红安县| 平果县| 微博| 青川县| 达日县| 英超| 年辖:市辖区| 洞口县| 白玉县| 海伦市| 大庆市| 伊春市| 巩留县| 潮安县| 廊坊市| 潮安县| 道真| 屯昌县| 肥城市| 莎车县| 呼玛县| 阿拉善左旗| 林州市| 乐平市| 惠来县| 宜昌市| 永泰县| 瓮安县| 台州市| 房产| 澎湖县| 内江市| 合水县| 武义县| 海南省| 汉源县| 隆安县| 四川省| 元阳县| 庄河市| 莒南县| 连州市| 新泰市| 芜湖县| 鹤庆县| 长兴县| 灵山县| 阿瓦提县| 太原市| 东丰县| 万年县| 剑阁县| 玛多县| 江口县| 叙永县| 龙门县| 英德市| 监利县| 新民市| 富平县| 龙山县| 仙居县| 亚东县| 东台市| 临湘市| 宾川县| 阳泉市| 高阳县| 柳林县| 桦川县| 通化县| 中西区| 平顶山市| 财经| 永泰县| 务川| 张家口市| 卢湾区| 石渠县| 临洮县| 夏河县| 从江县| 聂拉木县| 巴塘县| 四会市| 保康县| 介休市| 吴忠市| 蓝山县| 游戏| 庆阳市| 永城市| 甘孜| 斗六市| 七台河市| 和顺县| 景德镇市| 青阳县| 即墨市| 呼玛县| 寿阳县| 筠连县| 郎溪县| 台南县| 阳朔县| 新疆| 治多县| 临汾市| 临高县| 富蕴县| 舒兰市| 绩溪县| 广丰县| 长沙县| 台前县| 天长市| 黑龙江省| 八宿县| 武穴市| 广灵县| 淳化县| 雷州市| 栾城县| 根河市| 邵武市| 孟州市| 砚山县| 马龙县| 林芝县| 道孚县| 老河口市| 平阳县| 张家口市| 兴隆县| 关岭| 三门峡市| 安顺市| 南昌市| 昌宁县| 黄骅市| 六安市| 长葛市| 象山县| 崇明县| 社旗县| 洛阳市| 和硕县| 萨迦县| 建德市| 吴忠市| 漳浦县| 册亨县| 信丰县| 金秀| 威海市| 丽江市| 平谷区| 池州市| 辉县市| 莱芜市| 灵石县| 岢岚县| 大埔区| 尖扎县| 嘉鱼县| 交城县| 胶南市| 绵竹市| 济阳县| 南川市| 康保县| 昌宁县| 武威市| 八宿县| 东兰县| 武城县| 长春市| 莱西市| 淄博市| 绍兴县| 视频| 梨树县| 岑巩县| 兴国县| 敦煌市| 汾西县| 云梦县| 县级市| 玉龙| 龙州县| 永登县| 东港市| 湖口县| 阿城市| 赤峰市| 衡水市| 思南县| 舞阳县| 杭州市| 平罗县| 西平县| 卓尼县| 依安县| 双牌县| 龙门县| 西充县| 临沧市| 翼城县| 牡丹江市| 奈曼旗| 区。| 保德县| 施甸县| 崇明县| 华亭县| 巨野县| 囊谦县| 扶沟县| 榆林市| 射阳县| 武胜县| 柏乡县| 高雄市| 汶川县| 枞阳县| 长海县| 当雄县| 阿拉善盟| 平远县| 宁波市| 桂林市| 额济纳旗| 沅陵县| 阳曲县| 南丰县| 汕尾市| 攀枝花市| 宝鸡市| 财经| 上蔡县| 黄山市| 聊城市| 托克托县| 比如县| 桂阳县| 曲阳县| 穆棱市| 景洪市| 朝阳区| 新民市| 南岸区| 浠水县| 犍为县| 福建省| 凤城市| 出国| 莱州市| 泰来县| 定结县| 宁德市| 拉萨市| 南陵县| 泸定县| 乌鲁木齐县| 闽清县| 南平市| 济宁市| 米泉市| 定日县| 湘潭县| 三河市| 平塘县| 黄平县| 当涂县| 阿克苏市| 江门市| 大余县| 屯留县| 同江市| 林周县| 翁牛特旗| 许昌市| 曲阜市| 翁牛特旗| 南京市| 和平县| 阳东县| 邵东县| 信阳市| 黑河市| 曲麻莱县| 渑池县| 安图县| 怀来县| 广州市| 内丘县| 光泽县| 中方县| 宜良县| 韩城市| 龙江县| 沾化县| 鸡东县| 遵化市| 贵定县| 孟津县| 东海县| 西畴县| 嘉荫县| 老河口市| 疏附县| 兴和县| 平乡县| 广水市| 通化县| 高州市| 洪江市| 县级市| 乐东| 彭州市| 定日县| 乐昌市| 丹阳市| 城固县| 招远市| 报价| 汤原县| 湘乡市| 奉节县| 合水县| 凌源市| 靖江市| 铜梁县| 罗田县| 阳朔县| 安仁县| 枝江市| 泰兴市| 三都| 射阳县| 民勤县| 将乐县| 仁寿县| 琼中| 新建县| 宣汉县| 仁寿县| 定结县| 县级市| 沐川县| 喜德县| 巧家县| 安溪县| 会昌县| 永康市| 新和县| 资源县| 和龙市| 东乡族自治县| 保靖县| 论坛| 平邑县| 阿瓦提县| 庄河市| 沧州市| 华池县| 固原市| 犍为县| 沙坪坝区| 济阳县| 大宁县| 和静县| 红安县| 北川| 营口市| 德庆县| 湾仔区| 庆安县| 沙洋县| 花垣县| 大英县| 西城区| 黔南| 保山市| 皋兰县| 丰都县| 镇赉县| 新巴尔虎左旗| 屏边| 云和县| 武威市| 阳春市| 元谋县| http://m.jx1870handlev.fun http://jx1870fatv.fun http://wap.jx1870gov.fun http://m.jx1870headv.fun http://m.hz0j0r3vo.fun http://www.hz0j2r7vo.fun http://wap.hz0j3r9vo.fun http://m.jx1870foxv.fun http://www.jx1870flowerv.fun http://wap.jx1870leadv.fun http://wap.jx1870floorv.fun http://www.jx1870havev.fun http://wap.hz0j4r4vo.fun http://wap.jx1870identifyv.fun http://m.hz0j0r0vo.fun http://m.jx1870fatv.fun http://m.jx1870handlev.fun http://jx1870judgev.fun