![](/img/trans.png)
[英]Capitalize Every Other Letter in a String — take / drop versus head / tail for Lists
[英]identical head and tail operations on lists or vectors
我沒有LISP和列表處理方面的經驗,但是我有一組C ++ STL向量(或字符串),我需要在這些向量上執行以下操作:
IdenticalHead(v1,v2):返回v1和v2都以此序列開頭的最大序列。
IdenticalTail(v1,v2):返回v1和v2都以其結尾的最大序列。
IdenticalTailHead(v1,v2):返回以v1結束並以v2開頭的最大序列。
例如:
如果v1 =(a,b,c,e,f),v2 =(a,b,d,e,f),則:
IdenticalHead (v1, v2) = (a,b)
IdenticalTail (v1, v2) = (e,f)
如果v1 =(a,b,c),v2 =(b,c,g),則:
IdenticalTailHead (v1, v2) = (b,c)
我的問題是這些標准操作是使用LISP還是其他語言進行的? 他們有CDR和CAR等標准名稱嗎?
IdenticalHead和IdenticalTail基本上由Common Lisp函數MISMATCH提供 。
CL-USER 81 > (mismatch '(a b c e f) '(a b d e f))
2
CL-USER 82 > (mismatch '(a b c e f) '(a b d e f) :from-end t)
3
CL-USER 83 > (defun identical-head (s1 s2)
(let ((m (mismatch s1 s2)))
(if (numberp m)
(subseq s1 0 m)
s1)))
IDENTICAL-HEAD
CL-USER 84 > (identical-head '(a b c e f) '(a b d e f))
(A B)
CL-USER 85 > (defun identical-tail (s1 s2)
(let ((m (mismatch s1 s2)))
(if (numberp m)
(subseq s1 (1+ m))
s1)))
IDENTICAL-TAIL
CL-USER 86 > (identical-tail '(a b c e f) '(a b d e f))
(E F)
第三個功能更復雜:
CL-USER 87 > (defun identical-tail-head (s1 s2 &aux (l1 (length s1)))
(loop for i from 0 below l1
for m = (mismatch s2 s1 :start2 i)
when (and m (= (+ i m) l1))
do (return (subseq s1 i))))
CL-USER 88 > (identical-tail-head '(a e d b c d) '(b c d a f))
(B C D)
不,沒有這些的標准運算符。 但是identical-head
並不難寫:
(defun identical-head (l1 l2)
(and l1 l2 (equal (car l1) (car l2))
(cons (car l1) (identical-head (cdr l1) (cdr l2)))))
除了反轉輸入列表,調用identical-head
,然后反轉結果之外,我不知道一種編寫identical-tail
的簡便方法,因為列表僅允許向前遍歷,而不允許向后遍歷。
(defun identical-tail (l1 l2)
(reverse (identical-head (reverse l1) (reverse l2))))
這是我寫identical-tail-head
:
(defun identical-tail-head (l1 l2)
(labels ((starts-with-p (list prefix)
(cond ((null prefix) t)
((null list) nil)
((equal (car list) (car prefix))
(starts-with-p (cdr list) (cdr prefix))))))
(cond ((null l1) nil)
((starts-with-p l2 l1) l1)
(t (identical-tail-head (cdr l1) l2)))))
這不是一種非常有效的方法,因為它是O(n²),但是(再次)鑒於列表僅是向前遍歷的,所以我沒有想出更好的方法。
因為您提到“其他語言”,所以Haskell是一種Lispy語言,它確實對您要問的內容有慣用的方法。
longestPrefix xs ys = map fst (takeWhile (\(x,y) -> x == y) (zip xs ys))
zip
將其兩個參數列表的元素配對,並且takeWhile
是自描述的。
對於第二個變體,您只需要對參數和結果使用reverse
。 第三點涉及更多:
longestPrefixEnding xs ys = -- '(a e d b c d) '(b c d a f)
head [t | t <- tails xs, let p=longestPrefix t ys, p==t]
tails xs
等效於iterate tail xs
tails xs
,即列表[xs, tail xs, tail (tail xs), ...]
; tail
是cdr
的同義詞,而head
是car
同義詞:
Prelude Data.List> longestPrefix "abcef" "abdef"
"ab"
Prelude Data.List> longestPrefixEnding "aedbc" "bcdaf"
"bc"
Prelude Data.List> longestPrefixEnding "aebcabcd" "bcdaf"
"bcd"
Prelude Data.List> longestPrefixEnding "aebcabcdx" "bcdaf"
""
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.