在GNU CLISP 2.49中使用替换功能

时间:2015-12-09 04:17:27

标签: replace common-lisp

我在网上看到过例子并尝试在我的代码中使用它,但我觉得这很奇怪。当我执行

(replace "abcdef" "54321" :start1 2 :end1 5 :start2 0 :end2 2)

在GUN CLisp 2.49中它给出了我想要的东西,

"ab543f"

但是当我在文本编辑器中编写完全相同的代码并加载文件时,它无法正常工作。

attempt to modify a read-only string: "abcdef"

我想编写一个读取数字列表的函数,并将该字符串中的第一个数字替换为负值。

是否可以编写如下函数:

(defun rep4negative (readlist)
       (let ((no (car readlist))
             (negativeNo (- 0 no)))

             (replace readlist "negativeNo" ))

并且此函数将返回新的读取列表,例如

(rep4negative '5 1 2)→(-5 1 2)

2 个答案:

答案 0 :(得分:3)

我认为你的术语有点困惑。特别是,您已经写过要读取数字列表(精细),然后替换字符串中的第一个数字。嗯。假设你的意思是“列表”,我想你想要一个看起来像这样的转换:

(1 2 3) => (-1 2 3)
(10)    => (-10)
()      => ()

你可以用以下内容写出来:

(defun negate-first (list)
    (when list
        (cons (- (car list)) (cdr list))))

这是在行动:

[2]> (negate-first '(1 2 3 4))
(-1 2 3 4)
[3]> (negate-first '(10))
(-10)
[4]> (negate-first '())
NIL

或者,也许你想用它的否定替换所有出现的第一个数字,所以你得到

(1 2 3 1) => (-1 2 3 -1)

等等。为此,您可以使用以下代码:

(defun negate-first-throughout (list)
    (when list
        (substitute (- (car list)) (car list) list)))

尝试一下:

[2]> (negate-first-throughout '(1 2 3 1))
(-1 2 3 -1)
[3]> (negate-first-throughout '(1))
(-1)
[4]> (negate-first-throughout '())
NIL

如果你不是指这两件事中的任何一件,也许你需要在你的问题中更清楚......

修改

在下面的第一条评论中(添加明显缺少的关闭数据),你说你想要

((1 (2 1)) (2 (2 3)) (4 (4 3))) => ((-1 (2 1)) (-2 (2 3)) (-4 (4 3)))

您可以在列表上方映射#'negate-first,也可以将其全部写入一个,如下所示:

(defun negate-cars (lists)
  (mapcar (lambda (sublist)
            (cons (- (car sublist)) (cdr sublist)))
          lists))

测试:

[1]> (defun negate-cars (lists)
      (mapcar (lambda (sublist)
                (cons (- (car sublist)) (cdr sublist)))
              lists))
NEGATE-CARS
[2]> (negate-cars '((1 (2 1)) (2 (2 3)) (4 (4 3))))
((-1 (2 1)) (-2 (2 3)) (-4 (4 3)))

答案 1 :(得分:1)

1

Replace 破坏性地修改其第一个参数。

修改文字会产生不确定的后果。您正在尝试修改字符串文字。

在大多数典型用例中,您不会使用文字字符串,而是使用字符串生成或输入。

您可以先复制文字来修复您的示例。

(replace (copy-seq "abcdef") "54321" :start1 2 :end1 5 :start2 0 :end2 2)

2

首先一步一步地做。

(defun negate-first (list)
  (let ((first (first list))  ; get the first element
        (rest (rest list)))   ; the rest will be unmodified
    (cons (- first) rest)))   ; put the negative first before the rest

您可能很快就会想到这一点,因此您无需分配中间变量。然后你得到这个更短的代码:

(defun negate-first (list)
  (cons (- (first list)) (rest list)))