代码之家  ›  专栏  ›  技术社区  ›  Martin Buchmann

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

  •  0
  • Martin Buchmann  · 技术社区  · 7 年前

    我不确定我是否遗漏了一些非常基本的东西,但我想从文件中读入一个字符串,并在我以后的程序中用作符号列表,即。

    "8C TS" ((8 C) (T S))

    我知道我可以使用 split-sequence 库没有问题,但作为一个字符串,我最终得到的是一系列字符

    > (loop :for c :across "8C" :collect c)
    (#\8 #\C)
    

    是否可以按上述规定转换初始字符串,或者是否存在不应/无法转换的原因?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Svante    7 年前

    如果您想将卡片表示为通用数据结构,那么最好使用向量而不是列表。字符向量只是一个字符串,所以 (split-sequence #\space hand) ,给出 ("8C" "TS") ,应该足够了。你可以定义一手牌是一张牌的列表,一张牌是一个长度为2的字符串,包含value和suit,value和suit作为字符。

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

    (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))
    

    这将把值表示为整数,把suit表示为关键字。然后,您可能需要定义如下谓词 card= , card-suit-= , card-value-<