如何将字符串转换为符号列表?

时间:2017-11-03 06:41:59

标签: string common-lisp

我不确定我是否遗漏了一些非常基本的内容,但我想从文件中读取一个字符串,并在后来的程序中将其用作符号列表,即

((8 C) (T S))应该成为split-sequence

我知道我可以使用> (loop :for c :across "8C" :collect c) (#\8 #\C) 库分割初始字符串而不会出现问题,但是字符串是一系列字符,我最终会用

font-family

是否可以转换上面指定的初始字符串,或者有什么理由不应该/不能这样做?

1 个答案:

答案 0 :(得分:2)

如果您想将卡表示为通用数据结构,您可以使用向量而不是列表。字符向量只是一个字符串,因此(split-sequence #\space hand)给出("8C" "TS")就足够了。您将手定义为卡片列表,卡片长度为2的字符串包含值和套装,值和适合作为字符。

然后使用简单的阅读器访问属性:

(defun card-value (card)
  (aref card 0))

(defun card-suit (card)
  (aref card 1))

如果您想要更明确的方法,您可能更喜欢为每个方法定义类或结构:

(defclass hand ()
  ((cards :initarg :cards
          :reader hand-cards)))

(defclass card ()
  ((value :initarg :value
          :reader card-value)
   (suit :initarg :suit
         :reader card-suit)))

解析会创建这样的对象:

(defun read-hand (string &aux (upcased (string-upcase string)))
  (make-instance 'hand
                 :cards (mapcar #'read-card
                                (split-sequence #\space upcased))))

(defun read-card (string)
  (make-instance 'card
                 :value (case (aref string 0)
                              (#\T 10)
                              (#\J 11)
                              (#\Q 12)
                              (#\K 13)
                              (#\A 14)
                              (t (parse-integer (string (aref string 0)))))
                 :suit (intern (aref string 1) '#:keyword))

这会将值表示为整数,将套装表示为关键字。然后,您可能希望定义谓词,例如card=card-suit-=card-value-<等。