A function which identifies how many times a string is included in another one in lisp -


i block program lisp function mark how many times string included in another

i tried function sends me error:

*** - +: "abc" not 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)))))) 

thank

in general, when you're doing string processing, should try avoid calling subseq, since creates new string, , don't want doing string allocation. many of sequence processing functions in common lisp take start , end parameters, can specify parts of sequence you're looking for. function search looks occurrence of sequence within sequences , returns index of first occurrence. can call search repeatedly new :start2 values search farther , farther within string. instance:

(defun search-all (needle haystack &key key (test 'eql)                                      (start1 0)                                      (end1 (length needle))                                      (start2 0)                                      (end2 nil)                                      (overlaps nil))   "counts number of times needle appears in haystack. start1 , end1, , start2 , end2, bounding index designators of needle , haystack, respectively.  if overlaps true, overlapping occurrences counted separately."   (do* ((len1 (- end1 start1))           ; length of needle (constant)         (upd (if overlaps 1 len1))       ; how increment pos         (occurrences 0 (1+ occurrences)) ; occurrences, increments 1         (start2 start2 (+ pos upd))      ; start2, updated 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 nil, return occurrences 

there's 1 bit in there may bit confusing. variable bindings in do , do* loops have form (variable [init-form [update-form]]), , want init-form , update-form pos same, namely call search. in common lisp code, can use #n=form , use #n# refer same form again later. that's why i've used #1=(search …) init-form, , #1# update-form.

here examples:

;; find 'ab' within 'abcdabcd' (search-all "ab" "abcdabcd") ;;=> 2  ;; find 'cat' within 'one cat 2 cat 3 cat' (search-all "concatenate" "one cat 2 cat 3 cat" :start1 3 :end1 6) ;;=> 3  ;; find 'cat' within 'one cat 2 cat' (search-all "concatenate" "one cat 2 cat 3 cat" :start1 3 :end1 6 :start2             0 :end2 15) ;;=> 2  ;; fail 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 

Comments

Popular posts from this blog

Hatching array of circles in AutoCAD using c# -

ios - UITEXTFIELD InputView Uipicker not working in swift -

Python Pig Latin Translator -