2014-12-07 76 views
1

如果我有一個列表,其中包含3個使用全部大寫字符串相互分隔的不同對象,那麼我如何將它們捆綁到列表中?scheme/racket:將一個列表分成列表列表

我只有這麼遠

#lang racket 

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

得到有關「列表( 「折線」 「2」 「3」 ...... 「LINE」 「2」 「3」 ...) ((「POLYLINE」「2」「3」...)(「LINE」「2」「3」...))

+0

你能否提供一個例子(輸入和預期輸出)? – 2014-12-07 12:23:30

+0

當然,我在編輯中這麼做了! – KRC 2014-12-07 12:25:32

+0

'keyword'有什麼意義?你似乎沒有在任何地方使用它。 – 2014-12-07 13:34:54

回答

2

假設string-upper-case?已定義(比如,用andmap):

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

...我們可以寫一個通用的,簡單的,可以說是更習慣使用break從SRFI-1拆分實施列表分爲子列表與給定的條件開始,在這種情況下,作爲一個全大寫的字符串元素:

(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

這似乎是做你想做的事情,儘管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 '())) 
+0

在Scheme中,慣例使用'else',而不是'#t'作爲最後的條件。 – 2014-12-07 16:21:45

+2

對不起;老的Lisp習慣很難... – 2014-12-07 16:25:04

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