博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用函数式和命令式两种风格完成一道算法题
阅读量:6320 次
发布时间:2019-06-22

本文共 2711 字,大约阅读时间需要 9 分钟。

昨天偶然看见一个算法题,要求返回一个包含给定英文字符串(小写)中所有最长的升序字符串的列表,比如:

findmax('abc')-->['abc']findmax('afz')-->['afz']findmax('cba')-->['c','b','a']findmax('zfa')-->['z','f','a']findmax('abczabc')-->['abcz']findmax('abcabc')-->['abc','abc']

 

其实用常规思路来解还是没什么难度的.不过最近在学Scheme,便总是想着用函数式风格该怎么搞.最好能够完全避开赋值语句.

现在终于彻彻底底搞出来了,还是2种版本的函数式风格.纯的那种就是完全没有任何赋值语句的,甚至连方法语句都没有的(比如list.append(1)之类的).

感觉函数式编程很考验"倒推"以及"把复杂问题分解为简单问题'的能力.所谓"倒推",就是事先心中要设计好一个算法框架和数据结构(字典,列表,集合等等).命令式编程很难体会到设计的概念,大概是因为可以把一个变量改来改去,比较容易.

有时候我们需要的是某种值,这些值直接求是非常难的.但是把它转化成某种常见数据结构的衍生品,往往会变得简单.

# -*- coding:utf-8 -*-from collections import defaultdict#常规命令式 def findmax_c(s):    buf=defaultdict(list)    string=s if len(s)<2 else s[0]    for i in range(1,len(s)):        if s[i-1]<=s[i]:            string+=s[i]                   else:            buf[len(string)].append(string)            string=s[i]    buf[len(string)].append(string)                   return buf[max(buf)]#不是那么纯的函数式:def findmax_f(s):    def recur(s,mbr='',buf=defaultdict(list)):        if s=='':            buf[len(mbr)].append(mbr)            return buf[max(buf)]        if mbr=='' or mbr[-1]<=s[0]:            return recur(s[1:],mbr+s[0])        buf[len(mbr)].append(mbr)        return recur(s[1:],s[0])    return recur(s)def memory(function):    cache = {}    def memofunc(*nkw,**kw):        key=str(nkw)+str(kw)        if key not in cache:                        cache[key] = function(*nkw,**kw)        return cache[key]    return memofunc#纯函数式:def findmax_pf(s):    @memory    def recur(s,mbr=''):        if s=='':            return [mbr]            if mbr=='' or mbr[-1]<=s[0]:            return recur(s[1:],mbr+s[0])        return [mbr]+recur(s[1:],s[0])    return filter(lambda x:len(x)==len(max(recur(s),key=len)) ,recur(s))if __name__ == '__main__' :    for x in ['','a','aggz','abcaggza','abcabc','zfa','zfa']:        print '字符:{}命令式:{}函数式:{}纯函数:{}'.format(            x.ljust(10),            str(findmax_c(x)).ljust(16),            str(findmax_f(x)).ljust(16),            str(findmax_pf(x)).ljust(16))

 

最终结果:

>>> 字符:          命令式:['']            函数式:['']            纯函数:['']            字符:a         命令式:['a']           函数式:['a']           纯函数:['a']           字符:aggz      命令式:['aggz']        函数式:['aggz']        纯函数:['aggz']        字符:abcaggza  命令式:['aggz']        函数式:['aggz']        纯函数:['aggz']        字符:abcabc    命令式:['abc', 'abc']  函数式:['abc', 'abc']  纯函数:['abc', 'abc']  字符:zfa       命令式:['z', 'f', 'a'] 函数式:['z', 'f', 'a'] 纯函数:['z', 'f', 'a'] 字符:zfa       命令式:['z', 'f', 'a'] 函数式:['z', 'f', 'a'] 纯函数:['z', 'f', 'a']

 

其中,装饰器memory主要是让Python避免重复计算相同参数的函数..这是提高性能必须采取的手段,因为函数式编程要求你不能对一个值建立引用.

函数式编程要在默认参数上大做文章..通常命令式编程中的一些变量可以把它转化为默认参数来处理.

 

 

转载于:https://www.cnblogs.com/xiangnan/p/3397151.html

你可能感兴趣的文章
ArcGIS for Desktop入门教程_第八章_Desktop学习资源 - ArcGIS知乎-新一代ArcGIS问答社区...
查看>>
phpize php扩展模块安装
查看>>
authorization与URL授权
查看>>
JDK的目录结构及结构图
查看>>
值传递和引用传递-----函数参数传递的两种方式
查看>>
php随机密码函数的实例代码
查看>>
VC++中调用cmd的集中方式
查看>>
[LeetCode] Valid Word Abbreviation 验证单词缩写
查看>>
Shiro 学习笔记(二)——shiro身份验证
查看>>
JMeter 插件 Json Path 解析 HTTP 响应 JSON 数据(转)
查看>>
你不是真正的快乐
查看>>
201707舆情分析系统代码
查看>>
C#在自定义事件里传递自定义数据,使用EventArgs的姿势
查看>>
Memcached常用命令及使用说明
查看>>
Asp.net 前后台操作cookie 实现数据的循环下载
查看>>
MyGeneration学习笔记(9) :在WebService使用dOOdad时,对ToXml/FromXml的一点改进
查看>>
[开发笔记]MySQL & Python经验两则
查看>>
Delphi IDE 之 Object Inspector (对象检查器)
查看>>
关于母版页的按钮事件
查看>>
Using script to submit INV Manager to process MTI/MMTT
查看>>