簡體   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