Hello, I've been set the task to convert a string into a list of words within that string. As in, go through a string character by character, recording each character into a list, then when a space appears, break off that list and resume recording the next characters into a new list.
Eg
"Hello, world!" -> ("Hello" "world!")

I've been working on it for just over 2 days non-stop now, and everytime I try a solution, it just doesn't work. My main problem is trying to stop recording when I find a space, then start recording again. Since I've been working on it for so long, I have to much code to past all here, but here is what I think my most useful attempt is:

Note: I am trying to get this procedure to return a list of lists of characters, ie ( (#\I) (#\a #\m)). After I have this solved I can finish the rest by myself confidently.

(define [space? char]
; Check to see if a character is a space
  (equal? char #\space)
  )

(define [chars->list-of-chars char-list]
  
; If the list is empty, return a list with an empty list within it
  (if (empty? char-list)
      (list empty)
      
      ; otherwise if the first character in the list is a space
      (if (space? (first char-list))
          empty ; return an empty list
          
          ; else add the first character within a list, to the rest of the lists of characters (Recurse)
          (append (cons (first char-list) empty) (first-word (rest char-list))))
      )
  )

As you can see, when it finds a space, it returns empty (an empty list), which stops the recording of characters into the first list. As a result, if the first character in a string is a space, it returns an empty list, otherwise it will just return the first word.

This is the last section of an assignment that I have to do, I have the entire program working correctly, but without this piece, none of my hardwork will show =[

It's due in approx 24 hrs, so I would appreciate speedy replies

Thanks in advance

What is this "first-word" function? You haven't said anything about that. It seems to me like you meant to be calling chars->list-of-chars for that...

What you need to do is the following strategy: Make a function that does the following:

" Hello, world foobar captcha"
->
("Hello" . " world foobar captcha")

only instead of strings, have them be lists of characters... and if the input string has no more words, have it return #f or '(), or whatever suits you.

That's pretty similar to what you have, only instead of looking for space-characters, use char-alphabetic? or perhaps that in combination with char-numeric? to recognize word characters. It looks like your words aren't supposed to include punctuation, after all.

Once you have a function that returns the first word and the rest of the words in a cons pair, it's fairly simple to go from that to returning a list of words.

Sorry, forgot to change the procedure name when I recursed it :D

I think my main problem was that I was trying to remove the space chars from the list returned. Since I'm planning on returning a list of lists I can just apply the filter char-alphabetic? to each list afterwards. But my fundamental problem is much the same.

How can I tell it to put all the characters up to a space into one list, then continue, writing to a new list.

atm all I can return is
(first-word (string->list "I am a walrus"))
-> ((#\I) (#\space) (#\a) (#\m) (#\space) (#\a) (#\space) (#\w) (#\a) (#\l) (#\r) (#\u) (#\s) ())

All i need to change in this result is to have consecutive non-space characters to be within the same list (ie, change (#\a) (#\m) to (#\a #\m).

(define [space? char]
  (equal? char #\space)
  )

(define [first-word char-list]
  
  (if (empty? char-list)
      (list empty)
      
      ; If the character is alphabetic, record it
      (if (char-alphabetic? (first char-list)) 
          (cons (cons (first char-list) empty) (first-word (rest char-list)))
          
         ; If it's a space start recording the new list
          (if (space? (first char-list))
              (cons (list #\space) (first-word (rest char-list)))
              
          ; Otherwise just ignore it and move on to the next char
              (first-word (rest char-list)))
          )
      )
  )

Any ideas?

what programming language is this? And why is it not posted in the appropriate board? I'd move it but don't know what language it is.

I'd recommend forgetting everything and starting with this:

(define (parse-words chars current-word)
  ...)

In this case, 'chars' is your string and 'current-word' is the current word you're reading off the string.

For example, if you're converting the string "hello doctor foobar!", you'll end up recursing as in the following. (Note that where I draw strings, I really mean for there to be a list of chars. That would be a pain to write though.)

(parse-words "hello doctor foobar!" '())  ; "hello doctor foobar!" is really a list of chars
->
(parse-words "ello doctor foobar!" '(#\h))
->
(parse-words "llo doctor foobar!" '(#\e #\h))
(parse-words "lo doctor foobar!" '(#\l #\e #\h))
(parse-words "o doctor foobar!" '(#\l #\l #\e #\h))
(parse-words " doctor foobar!" '(#\o #\l #\l #\e #\h))
(cons (reverse '(#\o #\l #\l #\e #\h)) (parse-words (skip-leading-spaces " doctor foobar!") '()))

Now, this will have to be a helper-function. You'll want to have a function that converts the string to a list of chars and skips leading spaces before passing it to parse-words, and then recombines the words, represented as lists of chars, into string form.

And you'll need to write skip-leading-spaces. Maybe you should call it skip-leading-spaces-and-punctuation, or perhaps skip-leading-non-alphanumeric-chars. Or maybe 'drop-...' instead of 'skip-...'.

Oh, and this language is Scheme.

I love you Rashakil :D

That fixed my main problem, Thanks so much!!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.