用于打印和替换列表中元素的函数

时间:2015-04-07 01:33:46

标签: list scheme racket cdr

我正在尝试实现两个功能:subterm和replace。

  1. subterm将两个列表作为参数,并在耗尽第二个列表后在第一个列表中打印该元素。
  2. 例如,调用

    (subterm '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(4 2 2 1))

    应该返回

    8
    

    我提出了以下函数,它在列表中打印第n个元素:

    (define (subterm list n)                   
      (cond 
        ((null? list) '())             
        ((= n 1) (car list))              
        (else (subterm (cdr list) (- n 1)))))
    
    1. replace取3个列表,并返回替换达到的值的结果,其中列表的其余部分保持不变。
    2. 例如调用:

       (replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(11 12) '(4 2 2 1))
      

      应该返回:

      '(1 2 (3 4 5) (6 (7 ((11 12)) 9 10)))
      

      再次,我想出了这个代码,用第二个列表替换第一个列表中的第n个元素,保留第一个列表的其余部分:

      #lang racket
      (define (replace list elem n)
        (cond
          ((empty? list) empty)
          ((eq? n 1) (cons elem (cdr list)))
          (#t (cons (car list) (replace (cdr list) elem (- n 1))))))
      

      如何修改这些功能以获取两个列表?

      编辑1: 一些例子:

      > (subterm '(1 2 3 4 5) '(3))
      3
      
      > (subterm '(1 2 3 4 5) '(2))
      2
      
      > (subterm '(1 2 (3 4 5) 6 7) '(3 2))
      4
      

      考虑这个例子:

      > (subterm '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(4 2 2 1))
      8
      

      在上面的示例中,subterm采用2个列表。然后它读取第二个列表。第二个列表基本上告诉子项返回第四个元素(6(7(8)9 10)的第二个元素(7(8)9 10)的第二个元素((8))的第一个元素(8)第一个清单(1 2(3 4 5)(6(7(8)9 10)))。

      > (subterm '1 '())
      1
      
      > (subterm '(1 2 (3 4 5) (6 (7 (8) 9 10))) '())
      '(1 2 (3 4 5) (6 (7 (8) 9 10)))
      
      > (replace '(1 2 3 4 5) '(6 7 8) '(3))
      '(1 2 (6 7 8) 4 5)
      
      > (replace '(1 2 3 4 5) '(6 7 8) '(2))
      '(1 (6 7 8) 3 4 5)
      

      考虑这个例子:

      > (replace '(1 2 (3 4 5) 6 7) '(8 9) '(3 2))
      '(1 2 (3 (8 9) 5) 6 7)
      

      replace取三个列表:第一个列表是必须替换元素的列表。第二个列表包含必须放入第一个列表的新元素。第三个列表包含必须替换元素的位置。 因此,它基本上取代了第一个列表(1 2(3 4 5)6 7)的第3个元素(3 4 5)的第2个元素(4)。

      > (replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(11 12) '(4 2 2 1))
      '(1 2 (3 4 5) (6 (7 ((11 12)) 9 10)))
      
      > (replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) 1000 '(4 2 2 1))
      '(1 2 (3 4 5) (6 (7 (1000) 9 10)))
      
      > (replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) 'x '())
      'x
      
      > (replace '1 '(2 3 4) '())
      '(2 3 4)
      

3 个答案:

答案 0 :(得分:1)

首先,您将名称subterm用于两个不同的功能。让我们调用您为list-ref提供代码示例的版本,并在(car list) = 0而不是1时使n情况发生:

(define (list-ref list n)                   
  (cond 
    ((null? list) '())             
    ((= n 0) (car list))              
    (else (list-ref (cdr list) (- n 1)))))

事实证明,list-ref已经在racket库中了,所以你不应该首先实现它。所以使用它,你的subterm是微不足道的:

(define (subterm main-list path)
   (match path
     ('() #f)
     ((list n) (list-ref main-list (sub1 n)))
     ((cons n rest) (subterm (list-ref main-list (sub1 n)) rest))))

答案 1 :(得分:0)

我尝试编写replace程序代码。据我所知,我可以说这很难。但是我设法让它至少与你给出的例子一致。您可以阅读它,尝试理解它,然后尝试修改它以使用任何其他列表。我相信你需要一个额外的功能才能让它正常工作。

#lang racket
(require racket/trace)
(define (replace list elem n)
  (cond
    ((empty? list) empty)
    ((eq? n 1) (cons elem (cdr list)))
    (#t (cons (car list) (replace (cdr list) elem (- n 1))))))

(define replace-with-lists
  (λ (items replacement path res aux)
     (letrec ([splits (list-split-at items (car path) '())])
    (cond 
      ((empty? (cdr path)) 
;       (append
;        (car (list-ref res 0))
;       (list (append
;        (car (list-ref res 1))
;        (list (append (car aux) 
;               (replace (list-ref aux 1) replacement (car path))
;               (list-ref aux 2)))))))
       (let ([result (replace splits replacement 2)])
      (replace aux
               (append (car result)
              (list (cadr result))
              (caddr result)
              )
               2)))

      (else
       (replace-with-lists
             (list-ref splits 1)
             replacement
             (cdr path)
             (foldr cons (list (list 
                          (list-ref splits 0)
                          (list-ref splits 2)))
                    res)
             splits
             )))
    ))
    )

(define list-split-at
  (λ (lst place res)
    (cond
      ((empty? lst) res)
      ((= 1 place) (foldl cons
                          (list (cdr lst))
                          (foldr cons (list res) (list (car lst)))
                          ))
      (else
       (list-split-at (cdr lst) (- place 1) (foldr cons (list (car lst)) res))
       )
      )))
(trace replace-with-lists)

答案 2 :(得分:0)

好的,我在你的编程语言课上,我知道这个任务明天到期,所以我不想太多帮助,或者给你答案。如果你还在苦苦挣扎,我会尽力给你一些提示。以下提示适用于替换功能。

首先,您需要一个基本案例。我们通过以下方式获得了这个

  

(替换'(1 2(3 4 5)(6(7(8)9 10)))' x'())   ' X

     

(替换' 1'(2 3 4)'())   '(2 3 4)

为此,我们只需要一个检查空列表的条件语句。很明显,如果最后一个参数是一个空列表,我们需要"返回"倒数第二个论点。 (在你的代码中,这将是" elem"和" n")

现在来了困难的部分。一旦你意识到有多少内置函数scheme / racket,它就非常简单了。以下是我使用的唯一一个,但他们更容易解决问题。

(附加) (名单) (采取) (下降) (list-ref)//这个比任何东西更方便。

转入日期过后,我会发布我的解决方案。希望这有帮助。

编辑:由于这项任务需要几分钟,我会发布我的解决方案,因为我认为这不会被视为作弊。

lang racket

(define (subterm term1 lat)
  (cond
    [(eqv? lat '()) term1]
    [(eqv? (car lat)1) (subterm (car term1) (cdr lat))]
    [else (subterm (cdr term1) (cons(-(car lat)1)(cdr lat)))])
  )

(define (replace term1 term2 lat)
  (cond
    [(eqv? lat '()) term2]
    [else (append(take term1 (-(car lat)1)) (list(replace (list-ref term1 (-(car lat)1)) term2 (cdr lat))) (drop term1 (car lat)))]))

这些都是功能。