Тестирование на наличие подстроки в строке в Racket - PullRequest
0 голосов
/ 03 ноября 2019

Тестирование на наличие подстроки в строке в Racket.

Мой код показан ниже.

(define (check-for-substring/list loc loc-to-find)
  (cond [(empty? loc-to-find) true]
        [(empty? loc) false]
        [(char=? (first loc) (first loc-to-find))
         (or (check-for-substring/list (rest loc) (rest loc-to-find))
             (check-for-substring/list (rest loc) loc-to-find))]
        [else (check-for-substring/list (rest loc) loc-to-find)]))

(define (check-for-substring string substring)
  (check-for-substring/list (string->list string) (string->list substring)))

Примеры тестов приведены ниже.

(check-expect (check-for-substring "flag" "flagged") false)
(check-expect (check-for-substring "flagged" "flag") true)
(check-expect (check-for-substring "" "") true)
(check-expect (check-for-substring "a" "") true)

Примеры тестов, которые не работают с моим кодом:

(check-expect (check-for-substring "flaminegio" "flamingo") false)
(check-expect (check-for-substring "heiloght" "height") false)

Примечание: для тех из вас, кто не знаком с языком начинающего студента с сокращениями списка, не существует "локальной" функции, котораяпозволяет функциям быть определенными внутри функций, и вместо списка «минусов» используется «список». Кроме того, функция «length» выводит длину списка, а не строки. Вы можете запросить дополнительные разъяснения в комментариях.

1 Ответ

0 голосов
/ 03 ноября 2019

Вам необходимо «сбрасывать» подстроку каждый раз, когда вы не находите совпадение, в противном случае вы в конечном итоге сопоставите "" с полной строкой, которая, конечно, всегда будет возвращать true.

Простой способ сделать это - разделить задачу на два «цикла», один из которых пересекает всю строку, а другой проверяет единственное вхождение подстроки, начиная с текущей позиции вполная строка. Попробуйте это:

(define (check-for-substring string substring)
  (check-for-substring/list (string->list string) (string->list substring)))

(define (check-for-substring/list loc loc-to-find)
  (cond [(empty? loc-to-find) true]
        [(empty? loc) false]
        [(check-one loc loc-to-find) true]
        [else (check-for-substring/list (rest loc) loc-to-find)]))

(define (check-one loc loc-to-find)
  (cond [(empty? loc-to-find) true]
        [(empty? loc) false]
        [(not (char=? (first loc) (first loc-to-find))) false]
        [else (check-one (rest loc) (rest loc-to-find))]))

Работает как положено:

(check-for-substring "flag" "flagged")
=> #f

(check-for-substring "flagged" "flag")
=> #t

(check-for-substring "" "")
=> #t

(check-for-substring "a" "")
=> #t

(check-for-substring "flaminegio" "flamingo")
=> #f

(check-for-substring "heiloght" "height")
=> #f
...