打印和替换列表中元素的函数
Functions to print and replace elements in a list
我正在尝试实现两个功能:subterm 和 replace。
- subterm 将两个列表作为参数,并打印第一个列表中在耗尽第二个列表后到达的元素。
例如调用
(subterm '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(4 2 2 1))
应该return
8
我想出了以下打印列表中第 n 个元素的函数:
(define (subterm list n)
(cond
((null? list) '())
((= n 1) (car list))
(else (subterm (cdr list) (- n 1)))))
- replace 获取 3 个列表,returns 将达到的值替换为未更改的列表的其余部分的结果。
例如调用:
(replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(11 12) '(4 2 2 1))
应该return:
'(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 个列表。然后它读取第二个列表。第二个list基本上告诉subterm to return 第1个元素(8) 第2个元素((8)) 第2个元素(7(8) 9 10) 第4个元素(6(7(8))第一个列表的 9 10) (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 4 5) 的第二个元素 (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)
首先,您将名称 subterm
用于两个不同的函数。让我们将您提供的版本称为 list-ref
的代码示例,并在 n
= 0 而不是 1 时发生 (car list)
情况:
(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))))
我尝试编写 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)
好的,我是你们的编程语言class,我知道这个作业明天就要交了,所以我不想帮助太多,也不想给你答案。如果您仍在苦苦挣扎,我会尽力给您一些提示。以下提示适用于替换功能。
首先,您需要一个基本案例。我们得到以下内容
(replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) 'x '())
'x
(replace '1 '(2 3 4) '())
'(2 3 4)
为此,我们只需要一个检查空列表的条件语句。很明显,如果最后一个参数是一个空列表,我们需要 "return" 倒数第二个参数。 (在您的代码中,这将是 "elem" 和 "n")
困难的部分来了。一旦您意识到 scheme/racket 有多少内置函数,这真的很简单。这是我唯一使用的,但它们使解决问题变得容易得多。
(追加)
(列表)
(拿)
(降低)
(list-ref) //这个比什么都方便。
提交日期过后,我将post我的解决方案。希望这对您有所帮助。
编辑:由于这项作业在几分钟后到期,我将 post 我的解决方案,因为我认为这不会被视为作弊。
浪拍
(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)))]))
这些都是函数。
我正在尝试实现两个功能:subterm 和 replace。
- subterm 将两个列表作为参数,并打印第一个列表中在耗尽第二个列表后到达的元素。
例如调用
(subterm '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(4 2 2 1))
应该return
8
我想出了以下打印列表中第 n 个元素的函数:
(define (subterm list n)
(cond
((null? list) '())
((= n 1) (car list))
(else (subterm (cdr list) (- n 1)))))
- replace 获取 3 个列表,returns 将达到的值替换为未更改的列表的其余部分的结果。
例如调用:
(replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) '(11 12) '(4 2 2 1))
应该return:
'(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 个列表。然后它读取第二个列表。第二个list基本上告诉subterm to return 第1个元素(8) 第2个元素((8)) 第2个元素(7(8) 9 10) 第4个元素(6(7(8))第一个列表的 9 10) (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 4 5) 的第二个元素 (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)
首先,您将名称 subterm
用于两个不同的函数。让我们将您提供的版本称为 list-ref
的代码示例,并在 n
= 0 而不是 1 时发生 (car list)
情况:
(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))))
我尝试编写 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)
好的,我是你们的编程语言class,我知道这个作业明天就要交了,所以我不想帮助太多,也不想给你答案。如果您仍在苦苦挣扎,我会尽力给您一些提示。以下提示适用于替换功能。
首先,您需要一个基本案例。我们得到以下内容
(replace '(1 2 (3 4 5) (6 (7 (8) 9 10))) 'x '()) 'x
(replace '1 '(2 3 4) '()) '(2 3 4)
为此,我们只需要一个检查空列表的条件语句。很明显,如果最后一个参数是一个空列表,我们需要 "return" 倒数第二个参数。 (在您的代码中,这将是 "elem" 和 "n")
困难的部分来了。一旦您意识到 scheme/racket 有多少内置函数,这真的很简单。这是我唯一使用的,但它们使解决问题变得容易得多。
(追加) (列表) (拿) (降低) (list-ref) //这个比什么都方便。
提交日期过后,我将post我的解决方案。希望这对您有所帮助。
编辑:由于这项作业在几分钟后到期,我将 post 我的解决方案,因为我认为这不会被视为作弊。
浪拍
(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)))]))
这些都是函数。