Mar*_*ann 2 string iteration loops common-lisp
我有两个相同长度的字符串,它们只有一个字符不同,我想要一个相等的所有字符的字符串.所以基本上这样的东西,它评估一个字符串而不是一个字符列表:
(loop for a across "abcd"
for b across "abce"
when (char= a b) collect a)
Run Code Online (Sandbox Code Playgroud)
虽然性能在这里不是问题,但我发现(coerce ... 'string)围绕它表现很麻烦.
所以我想出了类似的东西
(loop with result = ""
for a across "abcd"
for b across "abce"
when (char= a b)
do (setf result (concatenate 'string result (string a)))
finally (return result))
Run Code Online (Sandbox Code Playgroud)
这工作但看起来不是很优雅.
(map 'string (lambda (a b) (when (char= a b) a)) "abcd" "abce")
Run Code Online (Sandbox Code Playgroud)
看起来更好,但不是因为工作NIL是不是一个字符时a和b不相等.
是否有一个更优雅的习惯用法来迭代一个字符串并获得一个字符串?
(loop with result = ""
for a across "abcd"
for b across "abce"
when (char= a b)
do (setf result (concatenate 'string result (string a)))
finally (return result))
Run Code Online (Sandbox Code Playgroud)
对于更长的字符串,重复连接不是一个好主意.
备择方案:
循环进入列表并强制转换为字符串
CL-USER 3 > (loop for a across "abcd"
and b across "abce"
when (char= a b) collect a into list
finally (return (coerce list 'string)))
"abc"
Run Code Online (Sandbox Code Playgroud)
使用流并将其转换为字符串
CL-USER 4 > (with-output-to-string (*standard-output*)
(loop for a across "abcd"
and b across "abce"
when (char= a b) do (write-char a)))
"abc"
Run Code Online (Sandbox Code Playgroud)
使用可调节的弦
CL-USER 5 > (loop with string = (make-array 0
:element-type 'character
:adjustable t
:fill-pointer 0)
for a across "abcd"
for b across "abce"
when (char= a b) do (vector-push-extend a string)
finally (return string))
"abc"
Run Code Online (Sandbox Code Playgroud)
另一种可能性是使用mismatchDavid Hodge的评论:
CL-USER> (defun f(a b)
(let ((pos (mismatch a b)))
(concatenate 'string (subseq a 0 pos) (subseq a (1+ pos)))))
F
CL-USER> (f "abcdefg" "abcxefg")
"abcefg"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |