繁体   English   中英

我如何编写一个 function 来提取列表的第 n 个元素?

[英]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) 的发展,这种方法可以应用于许多这样的问题。

(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)

(2) 添加带有签名目的存根,以及一个最小示例

#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)

(3) Run:注意测试通过(“run early and often”:使所有测试通过)

(function 被命名为take-multiple因为它根据 lon 中的数字多次从 los 中“获取”初始元素)

(4) 确定与要求相关的模板清单

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...)

(5) 通过适当替换通用标识符来编辑模板:

(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))) ]))

这不会运行,因为我们不知道要用什么替换....来解决这个问题

(6) 添加下一个最简单的例子:

(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))

(7) 完成代码,再添加一个例子来检查:

(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM