[英]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.