渐渐能够写出越来越长的程序了😋
CL-USER> (defstruct string-slice
(string-data nil :type string)
(begin-index 0 :type integer)
(end-index nil :type integer))
STRING-SLICE
CL-USER> (defun string-split-by-char (ch str)
(declare (type character ch)
(type string str)
(optimize (speed 3) (safety 1)))
(let ((last-index 0)
(len (length str))
(result nil))
(do ((i 0 (1+ i)))
((>= i len)
(push (make-string-slice :string-data str
:begin-index last-index
:end-index i)
result)
(nreverse result))
(if (eql ch (char str i))
(progn (push (make-string-slice :string-data str
:begin-index last-index
:end-index i)
result)
(setf last-index (1+ i)))))))
STRING-SPLIT-BY-CHAR
CL-USER> (string-split-by-char #\Space "To be, or not to be")
(#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 0
:END-INDEX 2)
#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 3
:END-INDEX 6)
#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 7
:END-INDEX 9)
#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 10
:END-INDEX 13)
#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 14
:END-INDEX 16)
#S(STRING-SLICE
:STRING-DATA "To be, or not to be"
:BEGIN-INDEX 17
:END-INDEX 19))
CL-USER> (defun slice-to-string (slice)
(declare (type string-slice slice)
(optimize (speed 3) (safety 1)))
(subseq (string-slice-string-data slice)
(string-slice-begin-index slice)
(string-slice-end-index slice)))
SLICE-TO-STRING
CL-USER> (mapcar #'slice-to-string
(string-split-by-char #\Space "To be, or not to be"))
("To" "be," "or" "not" "to" "be")
CL-USER>