任何现有的编程语言,特别是在Lisp或ML系列中,是否具有库函数来计算“从第一个开始到第二个开始”意义上的列表差异 - 我不确定它应该被称为究竟是什么 - 例如,如果输入为:
,则将字符串视为字符列表abcdef
def
然后输出
abc
答案 0 :(得分:3)
Common Lisp中的代码:
CL-USER 1 > (defun fusos (s1 s2)
(let ((pos (search s2 s1)))
(when pos (subseq s1 0 pos))))
FUSOS
CL-USER 2 > (fusos '(a b c d e f) '(d e f))
(A B C)
答案 1 :(得分:3)
已经有一个已接受的答案,但Common Lisp的LDIFF
(“列表差异”的缩写)仍然值得一提。它基于列表的结构(列表构成的缺点单元格)而不是列表的元素,因此“减去”的列表必须是与某些尾部相同的相同的缺点单元格的清单。它有点具体,但它肯定会计算列表差异。
CL-USER> (let* ((abcdef '(a b c d e f))
(def (cdddr abcdef)))
(ldiff abcdef def))
(A B C)
答案 2 :(得分:1)
由于注释中提到takeWhile
并且Haskell具有此函数,因此以下是在Haskell中实现所需结果的方法:
takeWhile (flip notElem ys) xs
你的例子是
takeWhile (flip notElem "def") "abcdef"
即,您可以从列表xs
中获取元素,只要它们不包含在列表ys
中即可。一旦找到ys
中包含的元素(或点击xs
的末尾),就会停止。
在标准ML中,它将是:
fun take_while p [] = []
| take_while p (x::xs) =
if p x then x :: take_while p xs
else []
编辑:上面,我认为规范是我们在第一个列表中停止,只要我们找到第二个列表中的(任意)元素。因此使用takeWhile
。但是,从OP来看,我不清楚实际的规格是什么。如果从输入(第一个列表)中删除现有后缀(第二个列表),那么解决方案当然是不同的。在Haskell,没有考虑效率,我们可以这样做:
removeSuffix [] ys = []
removeSuffix xs@(z:zs) ys
| xs == ys = []
| otherwise = z : removeSuffix zs ys