0

I'm just starting with Scheme.

I'm trying to use some procedures from String Library.

Here's what I need:

input: "ccaAaAaAa"

function: generate all strings substituting all possible aAa to aBa, one substitution only

output: "ccaBaAaAa" and "ccaAaBaAa" and "ccaAaAaBa"

Is there any easy way to do that? Maybe a procedure that return a list of index of pattern found?

Apparently the searching function string-contains only returns the first occurrence.

What I thought is: after producing the first string "ccaBaAaAa", trim to the first index of the pattern found: the original "ccaAaAaAa" becomes "AaAaAa". Repeat (recursively).

Thanks.

eric17859
  • 418
  • 1
  • 5
  • 17

3 Answers3

0

string-contains won't give you a list of all occurrences of the substring, but it will tell you whether there is one, and if there is, what its index is. It also allows you to restrict the search to a particular range within the string. Based on this, if you get a match, you can recursively search the rest of the string until you no longer get a match.

From there, you can do the substitution for each match.

Taymon
  • 24,950
  • 9
  • 62
  • 84
0

What is wrong by writing such a function?

(define (replace input)
  (let loop ((done '())
             (remaining (string->list input))
             (output '()))
    (if (pair? remaining)
        (if (char=? #\a (car remaining))
            (let ((remaining (cdr remaining)))
              (if (pair? remaining)
                  (if (char=? #\A (car remaining))
                      (let ((remaining (cdr remaining)))
                        (if (pair? remaining)
                            (if (char=? #\a (car remaining))
                                (loop (append done (list #\a #\A))
                                      remaining
                                      (cons (list->string
                                             (append done
                                                     (cons #\a
                                                           (cons #\B
                                                                 remaining))))
                                            output))
                                (loop (append done (list #\a #\A
                                                         (car remaining)))
                                      (cdr remaining)
                                      (reverse output)))
                            (reverse output)))
                      (loop (append done (list #\a (car remaining)))
                            (cdr remaining)
                            (reverse output)))
                  (reverse output)))
            (loop (append done (list (car remaining)))
                  (cdr remaining)
                  (reverse output)))
        (reverse output))))

(replace "ccaAaAaAa") ;=> ("ccaBaAaAa" "ccaAaBaAa" "ccaAaAaBa")

About 15 minutes work.

ceving
  • 21,900
  • 13
  • 104
  • 178
0

I thought there could be better string libraries that I didn't know about. But I end up doing what I'd proposed in the question. (For a general input case)

(define (aplicarRegra cadeia cadeiaOriginal regra n)
  (let* ((antes (car regra))
         (depois (cdr regra))
         (index (string-contains cadeia antes))
         (tamanho (string-length antes))
         (diferenca (- (string-length cadeiaOriginal) (string-length cadeia))))

    (if index
       (let* ((cadeiaGerada (string-replace cadeiaOriginal depois (+ index diferenca) (+ index diferenca tamanho))))

          (if(<= (string-length cadeiaGerada) n)
             (lset-union equal? (list cadeiaGerada) (aplicarRegra(substring cadeia (+ 1 index)) cadeiaOriginal regra n))
             (aplicarRegra (substring cadeia (+ 1 index)) cadeiaOriginal regra n)))
       (list))))

But thanks anyway!

eric17859
  • 418
  • 1
  • 5
  • 17