Umnoon Binta Ali
Umnoon Binta Ali

Reputation: 11

How do I find the number of characters in a string using scheme programming language?

I used string-length to get the number of characters but I am having difficulties in defining a recursive function. Should I convert the string to a list and then count the elements?

Upvotes: 0

Views: 546

Answers (3)

mnemenaut
mnemenaut

Reputation: 820

If the question is a puzzle "count characters in a string without using string-length", then maybe:

(define (my-string-length s)
  (define (my-string-length t n)
    (if (string=? s t)  n
        (my-string-length
          (string-append t (string (string-ref s n))) (+ n 1))))
  (my-string-length "" 0))

or:

(define (my-string-length s)
  (define (my-string-length n)
    (define (try thunk)
      (call/cc (lambda (k)
          (with-exception-handler (lambda (x)
              (k n))
            thunk))))
    (try (lambda ()
            (string-ref s n)
            (my-string-length (+ n 1)))))
  (my-string-length 0))

(but of course string-ref will be using the base string-length or equivalent)

Upvotes: 0

user5920214
user5920214

Reputation:

There's no useful way of doing this recursively (or even tail recursively): strings in Scheme are objects which know how long they are. There would be such an approach in a language like C where strings don't know how long they are but are delimited by some special marker. So for instance if (special-marker? s i) told you whether the i'th element of s was the special marker object, then you could write a function to know how long the string was:

(define (silly-string-length s)
  (let silly-string-length-loop ([i 1])
    (if (special-marker? s i)
        (- i 1)
        (silly-string-length-loop (+ i 1)))))

But now think about how you would implement special-marker? in Scheme: in particular here's the obvious implementation:

(define (special-marker? s i)
  (= i (+ (string-length s) 1)))

And you can see that silly-string-length is now just a terrible version of string-length.

Well, if you wanted to make it look even more terrible, you could, as you suggest, convert a string to a list and then compute the length of the lists. Lists are delimited by a special marker object, () so this approach is reasonable:

(define (length-of-list l)
  (let length-of-list-loop ([i 0]
                            [lt l])
    (if (null? lt)
        i
        (length-of-list-loop (+ i 1) (rest lt)))))

So you could write

(define (superficially-less-silly-string-length s)
  (length-of-list
   (turn-string-into-list s)))

But, wait, how do you write turn-string-into-list? Well, something like this perhaps:

(define (turn-string-into-list s)
  (let ([l (string-length s)])
    (let loop ([i 0]
               [r '()])
      (if (= i l)
          (reverse r)
          (loop (+ i 1)
                (cons (string-ref s i) r))))))

And this ... uses string-length.

Upvotes: 2

user9706
user9706

Reputation:

What is the problem with?

(string-length string)

Upvotes: 1

Related Questions