Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strings and lists

0 views
Skip to first unread message

Steve Gonedes

unread,
Jun 19, 1999, 3:00:00 AM6/19/99
to

Josef Eschgfaeller <e...@felix.unife.it> writes:

< I'm trying to improve
<
< (defun first-word (a)
< (let ((pos (position #\space a))) (if (not pos) a
< (subseq a 0 pos))))

Not sure what you mean by improve. This looks fine to me.

< In such algorithms for strings it is often not clear to me, in
< which cases it is convenient to introduce lists, and when it has
< sense to mix strings with lists.

Probably when you need to return a list of strings?

< I tried it also directly, as in
<
< (defmacro char-ok (a i) `(and (array-in-bounds-p ,a ,i) (char ,a ,i)))

It is probably best to write `char-ok' as a function and declare it
inline.

< (defun first-word (a)
< (do* ((word "" (push-char word x)) (i 0 (+ i 1))
< (x (char-ok a i) (char-ok a i)))
< ((or (not x) (char= x #\space)) word)))
<
< with
<
< (defun push-char (word x) (concatenate 'string word (list x)))
<
< - probably not efficient - or

I think the first version using position was the most effective means
of describing your intentions. Some would perhaps like declarations
for clarity, but they're very terse and typing them in is such a drag.

For run-time efficiency using declarations with position should be
fine.

(defun first-word (str)
(declare (optimize (speed 3) (safety 1)) (simple-string str))
(let ((pos (or (position #\Space str) -1)))
(declare (fixnum pos))
(if (minusp pos)
str
(subseq str 0 pos))))

You will probably gain a little bit of speed if you do the loop by
hand using do or loop, but I doubt how much time this will actually
shave.

(defun first-word (str)
(declare (simple-string str))
(do ((idx 0 (1+ idx))
(len (1- (length str)) (1- len)))
((char= (schar str idx) #\Space)
(subseq str 0 idx))
(declare (fixnum idx len))
(when (zerop len)
(return-from first-word str))))

Using loop, it could look like the following.

(defun first-word (str)
(or (loop for ch across str as idx upfrom 0
when (char= ch #\Space)
return (subseq str 0 idx))
str))

0 new messages