Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2010-02-18

KMRCLを眺める (91) POSITION-CHAR

| 22:30 | KMRCLを眺める (91) POSITION-CHAR - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (91) POSITION-CHAR - わだばLisperになる

今回はKMRCLのstrings.lispから、POSITION-CHARです。

名前の通り、指定した文字が、文字列の中で何番目に出現するかを調べる関数。

定義は、

(defun position-char (char string start max)
  (declare (optimize (speed 3) (safety 0) (space 0))
           (fixnum start max) (simple-string string))
  (do* ((i start (1+ i)))
       ((= i max) nil)
    (declare (fixnum i))
    (when (char= char (schar string i)) (return i))))

動作は、

(KL:POSITION-CHAR #\0 "0123401234" 0 100)
;⇒ 0

(KL:POSITION-CHAR #\0 "0123401234" 1 100)
;⇒ 5

というところ

最初SBCLで試してみていたのですが

;; SBCL 1.0.35
(KL:POSITION-CHAR #\0 "0123401234" 6 100)
;⇒ 16

となりました。16とはこれ如何に。

文字列の長さを越えると動作がおかしくなる様子。試しに、Allegro CLで実行してみました。

;; Allegro CL
(KL:POSITION-CHAR #\0 "0123401234" 6 100)
;>>> Index 10 out of bounds for schar of "0123401234"

なるほど、文字列の長さを越えるとエラーです。定義からすると、エラーになるのが正しそうです。

この辺は、最適化の影響かなということで、

(optimize (speed 3) (safety 0) (space 0))

(optimize (speed 3) (safety 3) (space 0))

に変えてみたところ普通にエラーを出すようになりました。

安心した動作をさせるためには、

(LET ((STR "0123401234"))
  (KL:POSITION-CHAR #\0 STR 6 (LENGTH STR)))
;⇒ NIL

のように書く必要がありそうですが、最適化された関数は使い方もそれなりに面倒になるようです。

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20100218