微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

右对齐文本Lisp

如何解决右对齐文本Lisp

我试图让我的Lisp代码输出正确的东西。我查看了格式(doc link)的文档,然后尝试以下操作

(format t "~10:<*~>")

问题是运行此代码可以给我以下信息:

     *         *
     *

而不是给我这样的东西:

   **
    *

下面是整个函数,尽管我认为这不是引起任何问题的函数

(defun triangle-print-neg (rows numStar)
   (cond
      ((= rows 0) (return-from triangle-print-neg nil)) ;If rows = 0,force exit
      ((< numStar (abs rows)) (progn
           (format t "~10:<*~>")
           (triangle-print-neg rows (+ numStar 1)) ;Call function again but with numStar + 1
      )); numStar < abs(rows) print("*")
      (t (progn
             (format t "~%")
             (triangle-print-neg (+ rows 1) 0)
       )) ; Else call triangle print neg with row+1,0
   )
)

谢谢

解决方法

鉴于您的潜在问题是打印一个三角形(大概是学习Lisp的练习的一部分),并且您(我想)对Common Lisp不太熟悉,所以我建议试图了解format字符串语言的详细信息,该语言多毛且与Lisp完全无关,除非它恰好嵌入在CL中,而只是编写一个函数来使用简单的函数打印操作。

您需要的两个简单的打印操作是:

  • princ会打印出没有修饰符的内容,例如换行符或引号;
  • terpri会打印换行符。

鉴于这两个操作,您可以编写一个过程princ-n-padded,该过程将打印n个字符的副本,并填充到给定的宽度,然后换行。您可以使用宽度为负的肮脏技巧来指示右边的填充。

这是一个程序:

(defun print-n-padded (c n width &optional (to *standard-output*))
  "Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified,if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
  (if (>= width 0)
      (dotimes (i width)
        (princ (if (< i n) c #\Space) to))
     (dotimes (i (- width))
       (princ (if (< i (- (- width) n)) #\Space c) to)))
  (terpri to))

现在

> (dotimes (i 10)
    (print-n-padded #\* (+ i 1) -10))
         *
        **
       ***
      ****
     *****
    ******
   *******
  ********
 *********
**********
nil

如您所见,这是简单易懂的代码,没有冗长且难以理解的format字符串。在现实生活中,您最终可能会想开始以平凡的方式开始使用format,但是通常情况下,编写符合您要求的代码相对于编写起来要简单得多,而您想要的只是相对简单一些充满线噪声字符串的代码。


如果您需要递归执行此操作,那么您也可以这样做:

(defun print-n-padded (c n width &optional (to *standard-output*))
  "Print a line with N copies of C in width |WIDTH|.
If WIDTH >= 0 then print left justified,if it is < 0 print right justified.
The optional TO argument is the stream to which to print."
  (if (>= width 0)
      (princ-ab c #\Space width (- width n) to)
    (princ-ab #\Space c (- width) n to))
  (terpri to))

(defun princ-ab (a b n m to)
  "print (with PRINC) a total of N copies of A or B,printing N-M of A
followed by M of B,to TO.  Do not print a newline"
  (cond  ((> n 0)
          (princ (if (<= n m) b a) to)
          (princ-ab a b (- n 1) m to))
         ((= n 0)
          nil)
         ((< n 0)
          (error "negative-creep"))))
,
(defun my-triangle (k)
   (format t "~10@a~&" (make-string k :initial-element #\a))
   (unless (zerop k)
     (my-triangle (decf k))))
MY-TRIANGLE

CL-USER> (MY-TRIANGLE 5)
     aaaaa
      aaaa
       aaa
        aa
         a
          
NIL

我使用~a,填充为10,左对齐@修饰符:https://lispcookbook.github.io/cl-cookbook/strings.html#justifying-on-the-left-

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。