lisp - 一个函数,它标识一个字符串在 lisp 中包含在另一个字符串中的次数

标签 lisp common-lisp

我阻止编写 lisp 函数来标记一个字符串在另一个字符串中包含的次数

我尝试了这个向我发送错误的函数:

*** - +: "abc"不是数字

(defun string-contain (string1 string2)
  (cond
   ((not (length string1)) nil) ; string1 est vide (pas besoin de le tester à chaque fois)
   ((> (length string1) (length string2)) nil) ; string1 est plus longue que chaine2
   ((string= string1 (subseq string2 0 (length string1))) string1) 
   (t (+ 1(string-include string1 (subseq string2 1))))))

谢谢

最佳答案

一般来说,当您进行字符串处理时,您应该尽量避免调用 subseq,因为它会创建一个新字符串,并且您不希望进行所有的字符串分配。 Common Lisp 中的许多序列处理函数都带有开始和结束参数,因此您可以指定要查找的序列的哪些部分。 search 函数在另一个序列中查找一个序列的出现并返回第一次出现的索引。您可以调用search重复使用新的 :start2 值在字符串中搜索得越来越远。例如:

(defun search-all (needle haystack &key key (test 'eql)
                                     (start1 0)
                                     (end1 (length needle))
                                     (start2 0)
                                     (end2 nil)
                                     (overlaps nil))
  "Counts the number of times that NEEDLE appears in HAYSTACK. START1
and END1, and START2 and END2, are bounding index designators of
NEEDLE and HAYSTACK, respectively.  If OVERLAPS is true, then
overlapping occurrences will be counted separately."
  (do* ((len1 (- end1 start1))           ; length of needle (constant)
        (upd (if overlaps 1 len1))       ; how much to increment pos
        (occurrences 0 (1+ occurrences)) ; occurrences, increments by 1
        (start2 start2 (+ pos upd))      ; start2, updated to pos+upd
        (pos #1=(search needle haystack  ; pos. of needle, or NIL
                        :start1 start1 :end1 end1
                        :start2 start2 :end2 end2
                        :test test :key key)
             #1#)) 
       ((null pos) occurrences))) ; when pos is NIL, return occurrences

其中有一点可能有点令人困惑。 dodo* 循环中的变量绑定(bind)具有 (variable [init-form [update-form]]) 形式,我们希望posinit-formupdate-form 相同,即对 search 的调用。在 Common Lisp 代码中,您可以使用 #n=form ,然后使用 #n# 稍后再次引用相同的表单。这就是为什么我使用 #1=(search …) 作为 init-form,然后使用 #1# 作为 更新表格

这里有一些例子:

;; Find 'ab' within a 'abcdabcd'
(SEARCH-ALL "ab" "abcdabcd")
;;=> 2

;; Find 'cat' within a 'one cat two cat three cat'
(SEARCH-ALL "concatenate" "one cat two cat three cat" :START1 3 :END1 6)
;;=> 3

;; Find 'cat' within 'one cat two cat'
(SEARCH-ALL "concatenate" "one cat two cat three cat" :START1 3 :END1 6 :START2
            0 :END2 15)
;;=> 2

;; Fail to find 'cat' in 'Cat'
(SEARCH-ALL "cat" "Cat")
;;=> 0

;; Find 'cat' in 'Cat'
(SEARCH-ALL "cat" "Cat" :TEST 'CHAR-EQUAL)
;;=> 1

;; Find 2 'aaa' in 'baaaaaab' (no overlaps)
(SEARCH-ALL "aaa" "baaaaaab" :OVERLAPS NIL)
;;=> 2

;; Find 4 'aaa' in 'baaaaaab' (with overlaps)
(SEARCH-ALL "aaa" "baaaaaab" :OVERLAPS T)
;;=> 4

关于lisp - 一个函数,它标识一个字符串在 lisp 中包含在另一个字符串中的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35058220/

相关文章:

function - 将 x 添加到列表的第 n 项的 lisp 函数

list - 如何迭代列表中的每个元素而不删除方案中的元素

lisp - 使用以下规范在 LISP 中编写 Foo 函数

functional-programming - 什么时候可以修改函数式语言中的变量?

format - 如何在 Lisp 中使用 FORMAT 输出波形符?

lisp - Common Lisp 中的 Web 开发

common-lisp - 无论如何, "probe"是普通 lisp 中的一种方法吗?

functional-programming - Common Lisp 中的 Eval

lisp - "Member"无法识别列表的成员

documentation - SBCL 标准库文档?