Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp lisp函数连接字符串列表_Common Lisp_String Concatenation - Fatal编程技术网

Common lisp lisp函数连接字符串列表

Common lisp lisp函数连接字符串列表,common-lisp,string-concatenation,Common Lisp,String Concatenation,我需要编写一个函数,将列表连接成字符串。示例: (concatString(引号(“hello”“world”))==>“hello world” 以下是我到目前为止的情况: (defun concatString (list) "A non-recursive function that concatenates a list of strings." (cond ((not (listp list)) (princ "Error: argument to concat

我需要编写一个函数,将列表连接成字符串。示例:

(concatString(引号(“hello”“world”))==>“hello world”

以下是我到目前为止的情况:

(defun concatString (list)
  "A non-recursive function that concatenates a list of strings."
  (cond
   ((not (listp list))
     (princ "Error: argument to concatNR must be a list")(terpri) ())) ; check if parameter is a list

  (if (not (null list)) ;check if list is not null
      (let ((result (car list)))
        (dolist (item (cdr list))
          (if (stringp item)
              (setq result (concatenate result item)))          
        )
      )
  )
)
当我尝试运行它时,我收到一条“Error:“hello”是非法类型说明符”消息。我已经尝试了很多方法来修改这个函数,但我还没有弄明白。有人有什么想法吗?

连接结果类型和rest 序列

这个应该有用

(concatenate 'string result item)
根据报告:


只需在列表上使用format函数,即可将所有内容转换为字符串,并将它们与正确的格式字符串连接起来

(defun my-concat( list )
  (format nil "~{~a~}" list))
如果要将它们与空格连接,请使用带有“~^”指令的此表单:

(defun my-concat( list )
  (format nil "~{~a~^ ~}" list))
如果您想过滤掉结果,您可以在格式化列表之前对其进行转换

(defun my-concat(list)
  (format nil "~{~a~^ ~}" (remove-if-not #'stringp list)))

串联
需要序列类型说明符作为其第二个参数。要连接两个字符串,应调用
concatenate
,如下所示:

(concatenate 'string "hello" "world")
代码中的另一个错误:在将列表的
car
分配给
result
之前,没有确保它是一个字符串。通过修复代码,我提出了以下实现:

(defun concatString (list)
  "A non-recursive function that concatenates a list of strings."
  (if (listp list)
      (let ((result ""))
        (dolist (item list)
          (if (stringp item)
              (setq result (concatenate 'string result item))))
        result)))

;; tests
> (concatString (list "hello" " world"))
"hello world"
> (concatString (list "hello" 1 2 3 " world"))
"hello world"
> (concatString (list "hello" 1 2 "3" " world"))
"hello3 world"
> (concatString (list 1 2 3 "hello" " world"))
"hello world"
以下对
concatString
的重新定义更有效,因为它不会创建许多中间字符串对象:

(defun concatString (list)
  "A non-recursive function that concatenates a list of strings."
  (if (listp list)
      (with-output-to-string (s)
         (dolist (item list)
           (if (stringp item)
             (format s "~a" item))))))

为什么把自己限制在清单上

(defun concatenate-strings (sequence)
  (reduce #'(lambda (current next)
              (if (stringp next)
                (concatenate 'string current next)
                current))
          sequence
          :initial-value ""))

要将序列连接到字符串,请使用
concatenate'string

(defun concat-strings (list)
  (apply #'concatenate 'string list))
要从列表中删除非字符串的内容,请使用
remove if not

(defun concat-strings (list)
  (apply #'concatenate 'string
         (remove-if-not #'stringp list)))
如果参数不是列表,则会通过
remove If not
发出错误信号。当然,您可以在前面添加断言,以给出更具体的错误消息,但它在这里并没有真正增加值

(defun concat-strings (list)
  (assert (listp list)
          "This is not a list: ~s." list)
  (apply #'concatenate 'string
         (remove-if-not #'stringp list)))
编辑:

正如雷纳所指出的,
apply
只适用于长度有限的列表。如果您没有理由相信列表的长度不能超过
调用参数限制
减1,则
减少
形式更好:

(defun concat-strings (list)
  (reduce (lambda (a b)
            (concatenate 'string a b))
          (remove-if-not #'stringp list)))
这是我的两分钱:

(defmacro concatString(&rest字符串)`(concatenate'字符串) (@strings))


对不起,我应该提到,如果它忽略列表中不是字符串的项目。因此,如果一个项目是一个数字,则不应将其添加到字符串中。是的,这会改变问题的范围相当大。您可以使用remove if not筛选出非字符串:(defun my concat(list)(格式nil“~{~a}”(remove if not#'stringp list)))我正在检查它是否是字符串,因为对于赋值,如果是数字,则不应将其添加到字符串中。非常感谢您,尽管修复成功了!!!=)这是相对糟糕的:您一直在重复连接创建新的结果字符串。这可能会产生大量的垃圾。@Rainer Joswig我如何修复它?再次访问时,应该注意,如果您想要连接更多的字符串,则使用流(例如,
,将输出转换为字符串)或预先分配结果字符串,然后填充它,效率会更高。
(defun concat-strings (list)
  (reduce (lambda (a b)
            (concatenate 'string a b))
          (remove-if-not #'stringp list)))