[英]How can i write a function which extracts the nth element of a list?
作为我任务的一部分,我被赋予了以下任务:
编写一个 function,它将两个列表作为输入,一个包含字符的列表 L1 和一个包含数字的列表 L2。 对于 L2 中包含的每个数字 n,function 将显示列表 L1 的前 n 个字符。 例如: L1 '("h" "e" "l" "l" "o" "w" "o" "r" "l" "d") L2 '(2 3 1 5 10) Output:他
帮助
H
你好
你好 r l d.
我知道 function 需要两个 arguments 但我不知道如何应用第二个列表,它就像一个选择器,它读取第二个列表中的每个数字并提取第一个列表中 position 中的字符。
( define two-sequences
( lambda ( l1 l2 )
(for/list ([ i l1 ] [ j l2 ])
我应该使用哪个 function 来执行此操作。
您需要打印列表的前 n 个元素。 这是你如何做到的:
要打印列表的前n
元素, lst
:
n
为零,则打印换行符;n
为 1,打印lst
的第一个元素和一个换行符;n
大于 1,打印lst
的第一个元素,一个空格,然后打印lst
的 rest 的n - 1
元素(提示:您可以使用您当前正在编写的 function 来执行此操作);n
是其他任何东西,那么这是一个错误。 将其写成一个过程:例如将其称为print-n
。 那么回答问题的程序是:
(define (print-ns l ns)
(for ([n (in-list ns)])
(print-n l n)))
和
> (print-ns '("h" "e" "l" "l" "o" "w" "o" "r" "l" "d") '(2 3 1 5 10))
h e
h e l
h
h e l l o
h e l l o w o r l d
在 Common Lisp 或 emacs lisp 中,您想要的这个 function 称为elt
,它给出列表的第 n 个元素。 - 在 Racket 中,你必须自己定义它:
(define (elt l n)
(cond ((empty? l) '())
((zero? n) (car l))
(else (elt (cdr l) (- n 1)))))
(elt '(a b c d e f) 3) ;;=> 'd
然而,在日常工作中,人们不会使用列表——必须像这样遍历列表——而是使用向量——通过索引直接访问向量,因此速度更快。
(vector-ref #("a" "b" "c" "d" "e" "f") 3) ;;=> "d"
#(...)
等于(vector...)
并从序列中创建一个矢量。
编写一个 function,它将两个列表作为输入,一个包含字符的列表 L1 和一个包含数字的列表 L2。 对于 L2 中包含的每个数字 n,function 将显示列表 L1 的前 n 个字符。
所需的 function 可以使用for/list
紧凑地编写,但是在学习 Scheme/Racket 时,使用基本的 Scheme 函数构建它会很有帮助,而无需了解所有for/xxxx
变体和选项。
问题可以分为两部分:(1)产生要显示的字符(2)如问题所示显示它们。
这个答案将使用系统的设计方法展示 (1) 的发展,这种方法可以应用于许多这样的问题。
require
开始(在 DrRacket 中):#lang racket
(require test-engine/racket-tests)
(define L1 '("h" "e" "l" "l" "o" "w" "o" "r" "l" "d"))
(define L2 '(2 3 1 5 10))
(test)
#lang racket
(require test-engine/racket-tests)
(define L1 '("h" "e" "l" "l" "o" "w" "o" "r" "l" "d"))
(define L2 '(2 3 1 5 10))
; *stub* ;; *signature*
(define (take-multiple los lon) ;; ListOfString ListOfNatural -> (ListOf ListOfString)
;; produce, for each n in lon, first n elements of los ; *purpose statement*
'() ) ; *stub body* (valid result)
;
(check-expect (take-multiple L1 '()) '() ) ; *minimal example*
(test)
(function 被命名为take-multiple
因为它根据 lon 中的数字多次从 los 中“获取”初始元素)
take-multiple
处理一个列表,所以尝试使用最常见的模板来处理这种参数,“自然递归”:
(define (fn lox) ;; ListOfX -> Y ; *template*: (for fn with list argument)
;; produce a Y from lox using natural recursion ;
(cond ;
[(empty? lox) ... ] ; (... = "base case value" ;; Y )
[else (.... ; (.... = "inventory fn(s)" ;; X Y -> Y )
(first lox) (fn (rest lox))) ])) ;
; *inventory fns*:
(take lox n) ;; ListOfX Natural -> ListOfX ; (included because "...first n elements of los")
(cons x lox) ;; X ListOfX -> ListOfX ; (included because required result is ListOf...)
(define (take-multiple los lon) ;; ListOfString ListOfNatural -> (ListOf ListOfString)
;; produce, for each n in lon, first n elements of los
(cond
[(empty? lon) '() ] ; '() deduced from above check-expect
[else (....
(first lon) (take-multiple los (rest lon))) ]))
这不会运行,因为我们不知道要用什么替换....
来解决这个问题
(check-expect (take-multiple L1 '(2)) '( ("h" "e") ) )
所以我们需要(.... 2 (take-multiple L1 '()))
=> '( ("h" "e") ) )
我们可以看到(take-multiple L1 '())
是'()
,并且("h" "e")
是(take L1 2)
所以(.... (first lon)
是(cons (take los (first lon))
:
(define (take-multiple los lon) ;; ListOfString ListOfNatural -> (ListOf ListOfString)
;; produce, for each n in lon, first n elements of los
(cond
[(empty? lon) '() ]
[else (cons (take los (first lon)) (take-multiple los (rest lon))) ]))
(check-expect (take-multiple L1 '(2 3)) '( ("h" "e") ("h" "e" "l") ) )
第一个 function 现已完成(运行(take-multiple L1 L2)
检查)。
要生成所需的显示格式,请使用此 function:
(define (display-elements lolox) ;; (ListOf (ListOfX)) ->
;; display elements of lolox with newlines between first level lists
(for-each (lambda (lox)
(for-each (lambda (x)
(display x) (display " "))
lox)
(newline))
lolox))
所以(display-elements (take-multiple L1 L2))
显示:
h e
h e l
h
h e l l o
h e l l o w o r l d
>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.