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
Post a Comment