Scheme String Help
I am trying to write a function that evaluates to the number of distinct characters in the input string str. So for example (distinct-char "eeeiicczz")
would return 4. I need some help with my code. This is what I have.
(define string-contains
(lambda (str char)
(if (equal? str "")
#f
(if (char=? (string-ref str 0) char)
#t
(if (not (char=? (string-ref str 0) char))
(string-contains (substring str 1 (string-length str)) char))))))
(define unique-chars
(lambda (str)
(cond
((equal? str "") "")
((equal? (string-length str) 1) (string-ref str 0))
(else
(if (equal? (string-contains (substring str 1 (string-length str)) (string-ref str 0)) #t)
(unique-chars (substring str 1 (string-length str)))
(string-append (substring str 0 1) (substring str 1 (string-length str))))))))
(define distinct-char
(lambda (str)
(string-length (unique-chars str))))
I am limited to 开发者_StackOverflowusing these Built in functions:
(if x y z), (cond ...),
(read)
(string-length x)
(string-ref str x)
(substring x y)
(string-append x y)
(equal? x y), (char=?)
(remainder x y), (quotient x y)
(max ...), (min ...)
(+ x y), (- x y), (* x y), (/ x y)
(> x y), (< x y), (<= x y), (>= x y)
(and x y), (or x y), (not x y)
Since it's possible to convert a string to a list, it would be much easier to do that and use the built in list functions. (Note: the following code is in Racket. Since it's pretty much Scheme, I'm assuming these functions exist. If they don't check your docs for something similar)
(define (distinct-char str)
(length (remove-duplicates (string->list str))))
Here is a template you can fill in. Replace the comments with what you think should happen in each situation. Good luck!
(define (empty-string? str)
( #| What property does an empty string have? Add a simple boolean expression here. |# )
(define (char-exists? str char)
(cond
[(empty-string? str) ( #| If the string is empty, does the character exist? |# )]
[else ( #| Check the first character in the string. If it is what we're looking for
we're done! If it's not call this function on the rest of the string. |# )]))
(define (unique-chars str)
(cond
[(empty-string? str) ( #| What should you return if the string is empty? |# )]
[(equal? (string-length str) 1) ( #| What should you return if the string is one character long? |# )]
[else ( #| If the character at the beginning of the string exists in the rest of the string, ignore it
and preform recursion on the rest of the string. If it doesn't, append the character to
the result of this function on the rest of the string. |# )]))
(define (distinct-char str)
(string-length (unique-chars str)))
One of the reasons you learn stuff in scheme is it trains you to build up useful building blocks yourself, and then hook those building blocks together.
In this case, the general approach I would recommend is to write a function:
(string-contains str ch)
That returns #t
or #f
depending on whether or not str
contains the character ch
, and then use that to define a function:
(unique-chars str)
that returns a string of the unique characters in str
(you scan str
, building up your answer, and at every spot see if the next character is already in the answer string you're building, and if not, add it to your answer string).
Then, the function you wanted is just
(string-length (unique-chars str))
You can keep and pass along a list of every distinct character that you've come across before. That way, every time you check a new character, you look it up in your list to see if you've already seen it before. If it's not in your list, then it's a new character and you can add it to your list.
Homework question, so I'm not writing code in the answer.
精彩评论