如何将方案中的列表拆分成n个大小相等的块? [英] How do you split a list in scheme into n evenly sized chunks?

查看:10
本文介绍了如何将方案中的列表拆分成n个大小相等的块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在试拍中的一些练习题,被困在这道题上了

我要做的是定义一个列表,如(Partition‘(1 2 3 4 5 6)3),然后调用Return’((1 2)(3 4)(3 4))。(三个大小相等的分区)

例如,(Partition‘(1 2 3 4)3)将提供输出 (1)(2)(3 4) 其中n为3是要创建的分区数

下面我试过解决这个问题

(define (threesize n xs)
  (let loop ([grouped '()] [xs xs] [l (length xs])
    (cond
      [(empty? xs)
       (reverse grouped)]
      [(<= l n)
       (loop (cons xs grouped) '() 0)]
      [else (let-values ([(taken dropped) (split-at xs n)])
              (loop (cons taken grouped)
                    dropped
                    (- l n)))])))
总的来说,我对编程和球拍非常陌生,所以请原谅我在这方面的技能。谢谢您

推荐答案

对于那些编程和游戏新手来说,看看问题是如何解决的可能很有趣 这样的问题可以使用 Htdf(How to Design Functions) 在Drracket中使用BSL(初学者语言)的设计方法。

存根开始,包含签名目的,以及最小检查-预期<;示例:
(注意:布局与HtDF约定略有不同)

(define (partition xs n) ;; (Listof X) Nat -> (Listof (Listof X)) ; *stub define* ;; *signature*
  ;; produce xs divided into n chunks                             ; *purpose statement*
  (list (list)))                                                  ; *stub body* (a valid result)

(check-expect (partition '() 1)  '( () ))                         ; *example*

这可以在Drracket中运行:

Language: Beginning Student with List Abbreviations
The test passed!
>

HtDF中的后续步骤是模板清单。有一个通用模板 对于带有列表参数的函数,因为可以看到该函数将具有 要列出元素,可以在库存中列出可能有用的功能

(define (fn lox) ;; (Listof X) -> Y                  ; *template*
  (cond                                              ;
    [(empty? lox) ... ]  #|base case|# ;; Y          ;
    [else (...           #|something|# ;; X Y -> Y   ;
            (first lox) (fn (rest lox))) ]))         ;
            
(take xs n-to-take) ;; (Listof X) Nat -> (Listof X)  ; *inventory* 
(drop xs n-to-drop) ;; (Listof X) Nat -> (Listof X)  ;

#| (take and drop are not in BSL, so define them now) |#
(define (take xs n) ;; (Listof X) Nat -> (Listof X)
  ;; produce initial n elements of xs
  (if (zero? n)
      '()
      (cons (car xs) (take (cdr xs) (- n 1)))))
      
(define (drop xs n) ;; (Listof X) Nat -> (Listof X)
  ;; produce rest of xs after n elements
  (if (zero? n)
      xs
      (drop (cdr xs) (- n 1))))
分区将包括重复获取和删除多个元素、数量 一般是(quotient (length xs) n),所以现在引入这个参数:

(define (partition xs n) ;; (Listof X) Nat -> (Listof (Listof X))
  ;; produce xs divided into n chunks of length (quotient (length xs) n) (when possible)
  (partition-at xs n (quotient (length xs) n)))

(define (partition-at xs n len) ;; (Listof X) Nat Nat -> (Listof (Listof X))
  ;; produce xs divided into n chunks of length len   (stub adapted from template)
  (cond
    [(= n 1) (list xs) ]
    [else    (error "not yet defined") ]))

(check-expect (partition    '(1 2) 1)   '( (1 2) ))
(check-expect (partition-at '(a b) 1 2) '( (a b) ))

查看下一个check-expects(下面)和模板,可以看到如何完成 partition-at(通用模板是一次处理一个列表元素,所以这里first变成takerest变成drop)):

(check-expect (partition-at '(a b) 2 1) '( (a) (b) ))
(check-expect (partition-at '(a b c d) 2 2) '( (a b) (c d) ))

(define (partition-at xs n len) ;; (Listof X) Nat Nat -> (Listof (Listof X))
  ;; produce xs divided into n chunks of length len (plus excess)
  (cond
    [(= n 1) (list xs) ]
    [else    (cons (take xs len)
                   (partition-at (drop xs len) (- n 1) len)) ]))

因此,完整的解决方案(给定了Take和Drop)以及其他一些测试是:

(define (partition xs n)  ;; (Listof X) Nat -> (Listof (Listof X))
  ;; produce xs divided into n chunks
  (partition-at xs n (quotient (length xs) n)))

(define (partition-at xs n len)  ;; (Listof X) Nat Nat -> (Listof (Listof X))
  ;; produce xs divided into n chunks of length len
  (cond
    [(= n 1) (list xs) ]
    [else    (cons (take xs len)
                   (partition-at (drop xs len) (- n 1) len)) ]))

(check-expect (partition '(1 2 3 4 5 6) 3) '((1 2) (3 4) (5 6)))
(check-expect (partition '(1 2 3 4) 3) '((1) (2) (3 4)))
(check-expect (partition '(1 2 3 4) 5) '(() () () () (1 2 3 4)))
(当然,这不是最有效的解决方案,但它似乎不需要很大的 直觉的飞跃,一旦HtDFsystematic program design method 已经学会了,简单的函数通常可以写下来,并通过构造来更正。

这篇关于如何将方案中的列表拆分成n个大小相等的块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆