一种函数,用于识别一个字符串在另一个Lisp中包含多少次 [英] A function which identifies how many times a string is included in another one in lisp

查看:315
本文介绍了一种函数,用于识别一个字符串在另一个Lisp中包含多少次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阻止对lisp函数进行编程,以标记一个字符串在另一个字符串中包含多少次

I block to program lisp function that mark how many times a string is included in another

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

I tried this function that sends me an error:

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

*** - +: "abc" is not a number

(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 在另一个序列中查找一个序列的出现,并返回第一个出现的索引.您可以使用新的:start2 值可在字符串中搜索越来越远的值.例如:

In general, when you're doing string processing, you should try to avoid calling subseq, since it creates a new string, and you don't want to be doing all that string allocation. Many of the sequence processing functions in Common Lisp take start and end parameters, so that you can specify which parts of the sequence you're looking for. The function search looks for an occurrence of a sequence within another sequences and returns the index of the first occurrence. You can call search repeatedly with new :start2 values to search farther and farther within the string. For instance:

(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

其中可能有些混乱. do do * 循环中的变量绑定的格式为(variable [init-form [update-form]]),我们希望 pos init-form update-form 相同,即调用 search .在Common Lisp代码中,可以使用#n = form ,然后使用 #n#稍后再次引用相同的表单.因此,我将#1 =(search…)用作 init-form ,然后将#1#用作更新表单.

There's one bit in there that may be a bit confusing. The variable bindings in do and do* loops have the form (variable [init-form [update-form]]), and we want the init-form and update-form for pos to be the same, namely a call to search. In Common Lisp code, you can use #n=form and then use #n# to refer to the same form again later. That's why I've used the #1=(search …) as the init-form, and then #1# as the update-form.

以下是一些示例:

;; 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中包含多少次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆