string - 将多项式格式化为范式>(如何让最终结果变成lisp中的字符串?(包括所有函数))
问题描述
我目前正在写一个关于输入 P 的函数是正常形式的 PExpr 。以以下“常识”格式输出表示 P 的字符串
这是我现在得到的:</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 命令吗?希望有人能回答我的问题...谢谢
解决方案
princ
, print
, ecc等函数。执行两个不同的任务:
- 他们在标准输出上打印他们的参数,通常是终端,但如果特殊变量
*standard-output*
是反弹的,则可能会有所不同; - 它们返回打印为语言值的参数。
例如:
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(通过阅读 call 之后的两行可以清楚地看出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
with first parameterNIL
而不是 print 将其转换为字符串(例如(format () "~a" expression)
),然后concatenate
在组合不同的字符串时将所有这些字符串转换为一个部分(再次使用format
或concatenate
)。这需要对您的程序进行更多更改。
推荐阅读
- html - Angular 6中不相关的模板解析错误
- qlikview - 如何在最大/最后日期之前获得日期并在整个表上重复该过程?
- python - 如何修复'bool'对象没有属性'get'
- asp.net-core - 如何读取从 asp.net 核心 API 生成的“Set-Cookie”?
- http - OIDC:在长时间运行的服务器操作期间保持访问令牌有效
- javascript - 将图像拖放到 div 上
- ios - 按下 UIAlertViewController 行时更改背景颜色
- python - 为什么我的装饰器按这个顺序执行代码?
- c# - 如何从 c# windows 应用程序向 PHP 服务器发送包含对象数组的 POST 请求?
- c# - POST 带有 URL 参数但正文为空时如何使用 ServiceStack 的 ProxyFeature?