scheme / racket:将列表分成列表列表

时间:2014-12-07 12:20:34

标签: scheme racket

如果我有一个包含3个不同对象的列表,这些对象用全大写字符串相互分隔,我该如何将它们捆绑到3个列表的列表中?

我只是到目前为止

#lang racket

(define (test-string4 lst keyword)
  (let ((kw (string-upcase keyword)))
    (cond ((null? lst) '())
          ((string-upper-case? (car lst))
           (list 

列出'(" POLYLINE"" 2"" 3" ..." LINE"&#34 ; 2"" 3" ...) 它应该分解为(" POLYLINE"" 2"" 3" ...)(" LINE"& #34; 2"" 3" ...))

3 个答案:

答案 0 :(得分:2)

假设string-upper-case?已经定义(例如,使用andmap):

(define (string-upper-case? str)
  (andmap char-upper-case?
          (string->list str)))

...我们可以使用SRFI-1中的break编写一个通用的,更简单的,可以说是更惯用的实现,将列表拆分为具有以给定条件开头的元素的子列表,在本例中为全大写字符串:

(require srfi/1)

(define (splitter pred? lst)
  (if (empty? lst)
      empty
      (let-values ([(data tail) (break pred? (rest lst))])        
        (cons (cons (first lst) data)
              (splitter pred? tail)))))

每个元素序列的长度并不重要,只要我们尊重关键字是全大写字符串的约定,我们甚至不必传递关键字列表。例如:

(splitter string-upper-case?
          '("POLYLINE" "2" "3" "4" "LINE" "2" "3" "TEST" "1"))

=> '(("POLYLINE" "2" "3" "4") ("LINE" "2" "3") ("TEST" "1"))

答案 1 :(得分:1)

这似乎可以做你想要的,虽然string-upper-case?似乎没有在球拍中定义。

(define (splitter lst curr)
  (cond ((null? lst)  ; Put current "object" in a list
         (cons curr '()))

        ((string-upper-case? (car lst)) ; Starting a new "object"
         (let ((rslt (splitter (cdr lst) (list (car lst)))))
           (if (null? curr)
               rslt ; This is the only object
               (cons curr rslt)))) ; Add last-finished object to front of result

        (else ; Continue w/ current "object"
         (splitter (cdr lst) (append curr (list (car lst)))))))

(define (test-string4 lst)
  (splitter lst '()))

答案 2 :(得分:1)

我想知道您的数据结构是否真的适合您的需求,但我们继续:

首先我们定义take-right-until,它会根据谓词f拆分最右边的子列表:

(define (take-right-until lst f)
  (let loop ((spl1 (reverse lst)) (spl2 null) (found #f))
    (if (or found (null? spl1))
        (values (reverse spl1) spl2)
        (let ((c (car spl1)))
          (loop (cdr spl1) (cons c spl2) (f c))))))

测试:

> (take-right-until '("POLYLINE" "2" "3" "LINE" "4" "5" ) (curryr member '("POLYLINE" "LINE")))
'("POLYLINE" "2" "3")
'("LINE" "4" "5")
> (take-right-until '("POLYLINE" "2" "3") (curryr member '("POLYLINE" "LINE")))
'()
'("POLYLINE" "2" "3")

然后test-string4

(define (test-string4 lst kwds)
  (define kw (map string-upcase kwds))
  (define f (curryr member kw))
  (let loop ((lst lst) (res null))
    (if (null? lst)
        res
        (let-values (((spl1 spl2) (take-right-until lst f)))
          (loop spl1 (cons spl2 res))))))

测试:

> (test-string4 '("POLYLINE" "2" "3" "LINE" "4" "5" ) '("polyline" "line"))
'(("POLYLINE" "2" "3") ("LINE" "4" "5"))
> (test-string4 '("POLYLINE" "2" "3" "LINE" "4" "5" "SQUARE" "6" "7" "8") '("polyline" "square" "line"))
'(("POLYLINE" "2" "3") ("LINE" "4" "5") ("SQUARE" "6" "7" "8"))