用函式式和命令式兩種風格完成一道演算法題

2022-04-28 22:51:19 字數 3391 閱讀 4660

昨天偶然看見乙個演算法題,要求返回乙個包含給定英文本串(小寫)中所有最長的公升序字串的列表,比如:

findmax('

abc')-->['

abc'

]findmax(

'afz

')-->['

afz'

]findmax(

'cba

')-->['

c','

b','a'

]findmax(

'zfa

')-->['

z','

f','a'

]findmax(

'abczabc

')-->['

abcz']

findmax(

'abcabc

')-->['

abc','

abc']

其實用常規思路來解還是沒什麼難度的.不過最近在學scheme,便總是想著用函式式風格該怎麼搞.最好能夠完全避開賦值語句.

感覺函式式程式設計很考驗"倒推"以及"把複雜問題分解為簡單問題'的能力.所謂"倒推",就是事先心中要設計好乙個演算法框架和資料結構(字典,列表,集合等等).命令式程式設計很難體會到設計的概念,大概是因為可以把乙個變數改來改去,比較容易.

有時候我們需要的是某種值,這些值直接求是非常難的.但是把它轉化成某種常見資料結構的衍生品,往往會變得簡單.

#

-*- coding:utf-8 -*-

from collections import

defaultdict

#常規命令式

deffindmax_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

: string=s[i]

return

buf[max(buf)]

#不是那麼純的函式式:

deffindmax_f(s):

def recur(s,mbr='',buf=defaultdict(list)):

if s==''

:

return

buf[max(buf)]

if mbr==''

or mbr[-1]<=s[0]:

return recur(s[1:],mbr+s[0])

return recur(s[1:],s[0])

return

recur(s)

defmemory(function):

cache ={}

def memofunc(*nkw,**kw):

key=str(nkw)+str(kw)

if key not

incache:

cache[key] = function(*nkw,**kw)

return

cache[key]

return

memofunc

#純函式式:

deffindmax_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避免重複計算相同引數的函式..這是提高效能必須採取的手段,因為函式式程式設計要求你不能對乙個值建立引用.

函式式程式設計要在預設引數上大做文章..通常命令式程式設計中的一些變數可以把它轉化為預設引數來處理.

Java中的兩種單例模式 餓漢式和懶漢式

問題 首先我們需要來考慮2件事情,既然單例模式需要保證系統中最多只有乙個這樣的物件事例,那麼我怎麼才能確保只能有乙個例項呢?構造方法 如果構造方法是 public,那麼任何類都可以 new 我的物件,不能保證單例,所以單例模式構造方法一定是 private的 如果構造方法是 private的,那麼我...

關於單例模式的兩種經典實現(餓漢式和懶漢式)

餓漢式單例,類載入在整個生命週期中只會被載入一次 public class singleton1 提供指向自己的私有靜態引用 類載入時就建立 執行緒安全 private static singleton1 singleton1 newsingleton1 給外部獲取例項的方法 public stat...

token和session兩種登陸方式的理解

最近專案中有用到token和session,但是我對此不是很理解,所以特地整理下學習筆記,已便自己檢視,也可以幫助到更多跟我一樣有疑惑者。一 我們先解釋一下他的含義 1 token的引入 token是在客戶端頻繁向服務端請求資料,服務端頻繁的去資料庫查詢使用者名稱和密碼並進行對比,判斷使用者名稱和密...