string - Format polynomial to normal form> (如何让最后的结果在lisp中变成string?(包括所有函数))

标签 string loops printing lisp common-lisp

我目前正在写一个关于输入 P 的函数是一个正常形式的 PExpr。按照以下“常识”格式输出代表P的字符串

这是我现在得到的:

(defun writepoly (a b start)
  (cond
    ((and (minusp a) start) 
      (princ "-"))
    ((not start)
      (princ (if (plusp a) " + " " - "))))

  (cond
    ((not (equal (abs a) 1))
    (princ (abs a))))

  (cond
    ((equal (abs b) 1)
      (princ "x"))
    ((> (abs b) 1)
      (princ "x")
      (princ "^")
      (princ b))))


(defun print-pexpr (P)
(loop for (a . b) in P
  for start = t then nil

    do (write-to-string (writepoly a b start))

我确实得到了正确的结果,就像

(print-pexpr '((-1 . 10) (-23 . 0)))

-x^10 - 23
NIL

但是当我做测试用例的时候

(defun test-case (ID Test Result)
    (if (equal Test Result)
        (format nil "Test ~S OK" ID)
        (format nil "FAIL: Test ~S expected ~S got ~S" ID Result Test)
    )
   )

(test-case 6.4
    (print-pexpr '((-1 . 10) (-23 . 0)))
    "-x^10 - 23"
)

输出是:

"FAIL: Test 6.4 expected \"-x^10 - 23\" got NIL

如何更改我的函数以便我可以获得字符串...?我不应该使用 princ 命令吗?希望有人能回答我的问题...谢谢

PS:我复制了Lisp Formatting Polynomial中的方法

最佳答案

princprint、ecc 等函数。执行两个不同的任务:

  1. 他们在标准输出上打印他们的参数,标准输出通常是终端,但如果特殊变量 *standard-output* 是 rebound 的话,可能会有所不同;
  2. 它们返回作为语言值打印的参数。

例如:

CL-USER> (+ (print 1) (print 2))

1   ; <- printed by (print 1), which returns also 1
2   ; <- printed by (print 2), which returns also 2
3   ; <- the sum of 1+2, printed by the REPL, not by the program!

因此,如果您尝试例如(writepoly -1 10 t),您会得到:

CL-USER> (writepoly -1 10 t)
-x^10   ; <- printed by writepoly
10      ; <- returned by writepoly

换句话说,您的程序打印一些东西并返回其他东西,就像最后一个函数,您在其中打印多项式但返回 NIL(通过阅读调用 print-pexpr 之后的两行可以清楚地看出>), 这就是错误的原因。

如何修改程序以返回打印的字符串?基本上有两种可能。第一个是 Rainer Joswing 的回答所建议的,使用了两个东西:函数 with-output-to-string , 这会创建一个新的输出流,其中所有“打印”的内容都在最后作为单个字符串返回,第二个通过给出该流的名称 *standard-output*,其中练习“指示”所有打印命令(没有显式流参数)在该字符串上打印(否则您应该通过显式添加要打印的流来更改所有打印调用)。

所以你可以改变你的最后一个功能:

(defun print-pexpr (P)
  (with-output-to-string (*standard-output*)
    (loop for (a . b) in P
      for start = t then nil
      do (writepoly a b start))))

另一种方法是,不是将结果打印到某个流,而是使用 format 将其转换为字符串。使用第一个参数 NIL,而不是打印,(例如 (format () "~a"expression)),然后是 concatenate当组合不同的部分(再次使用 formatconcatenate)时,所有这些字符串变成一个单独的字符串。这需要对您的程序进行更多更改。

关于string - Format polynomial to normal form> (如何让最后的结果在lisp中变成string?(包括所有函数)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54858009/

相关文章:

javascript - 数组中的 indexOf 行为不正确

java - 如何在循环中创建 try block ?

ios - UIPrintInteractionController 设置最小份数

c# - WebBrowser.Print() 等到完成。 。网

c# - 检索所有可用打印机驱动程序的列表(如添加打印机向导)

python - 判断一个句子是英文概率的比较简单的方法是什么?

python - 如何对字符串进行类型检查

python - 如何使用变量列表来创建 sql 查询字符串?

python - 如何在 Pandas 中选择具有特定字符串模式的行?

Javascript - Tic Tac Toe - 如何遍历获胜条件?