CanadianBeaver
CanadianBeaver

Reputation: 81

In Racket how do I consume a String sentence and create a listof String that consists of every word in that sentence?

Essentially, I just want to convert a string sentence into a list of individual string words using DrRacket/Scheme. I currently am using Intermediate Student with Lambda so that may limit some functions I can use but any assistance would be appreciated. For instance I want

(split-string "the man over there is close") to yield

(list "the" "man" "over" "there" "is" "close")

Upvotes: 0

Views: 1079

Answers (2)

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 10108

Tail call recursive version

For single character separators.

(define (split-string s (sep #\space))
  (define (rec-split sl sep (acc '()) (h-acc '()))
    (cond ((empty? sl) (reverse (map (lambda (isl) (list->string isl))
                                     (cons (reverse h-acc) acc))))
          ((char=? (car sl) sep) (rec-split (cdr sl) sep (cons (reverse h-acc) acc) '()))
          (else (rec-split (cdr sl) sep acc (cons (car sl) h-acc)))))
  (rec-split (string->list s) sep))
> (split-string "the man over there is close")
;; '("the" "man" "over" "there" "is" "close")

Upvotes: 0

Óscar López
Óscar López

Reputation: 236150

This problem is slightly tricky. For starters, you need to think about the input string as a list of chars. Every time a space is encountered, we know that a new word is complete.

We can keep track of the current word in a variable, and use an accumulator for storing whole words, being careful of reversing the intermediate values, because we'll be consing them so they'll be in reverse. This is what I mean:

(define (split-string lst)
  (let loop ((acc '()) (current '()) (chars (string->list lst)))
    (cond ((null? chars)
           (reverse (cons (list->string (reverse current)) acc)))
          ((char=? (car chars) #\space)
           (loop (cons (list->string (reverse current)) acc)
                 '()
                 (cdr chars)))
          (else
           (loop acc
                 (cons (car chars) current)
                 (cdr chars))))))

It works as expected:

(split-string "the man over there is close")
=> '("the" "man" "over" "there" "is" "close")

Upvotes: 1

Related Questions