在字符串列表中查找具有所需前缀的字符串

时间:2019-03-23 19:34:16

标签: racket

我需要定义函数plPrefixContained –使用5个字符串,并且 返回第一个包含字符串"pl"作为前缀的字符串(如果这样的话) 存在,然后返回#f

我想做的是使用前缀功能遍历列表中的所有字符串并检查其前缀,将其放入新列表中并输出第一个字符串作为结果。 (我将在以后处理#f情况)我的代码在下面,但它一直给我错误-

first: contract violation
  expected: (and/c list? (not/c empty?))
  given: '()

任何帮助将不胜感激

(: plPrefixContained : String String String String String -> String)
(define (plPrefixContained x y z w v) 
  (list-ref (prefixes (list x y z w v) '()) 0))


(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
  (cond
    [(and (eq? (string-ref (first lis) 0) "p") (eq? (string-ref (first lis) 1) "l"))
     (cons (first lis) em)]
    [else
     (prefixes (rest lis) em)]))

这就是我希望输出类似的方式

(test (plPrefixContained "yypl" "opl" "lpTT" "plpl" "lol")
      =>
      "plpl")

1 个答案:

答案 0 :(得分:1)

有两个问题:

  • 内涵相等eq?,而不是equal?string=?之类的延伸相等
  • 比较字符串/字符,而不是比较字符/字符或字符串/字符串

您正在使用eq?,这总是让我感到怀疑。 eq?使用“内涵”相等,它基本上是指针相等,这意味着在内存中分配的某个字符串即使具有相同字符也不一定是eq?。您可以通过(eq? "abc123" (string-append "abc" "123"))看到它。

如果要处理字符串,列表或任何其他“包含”事物的数据,则应避免使用eq?。相反,您应该使用“扩展”相等谓词,例如equal?,或者甚至更好地使用特定于期望值类型的谓词,例如string=?。它们的行为比eq?好:

> (eq? "abc123" (string-append "abc" "123"))
#f
> (equal? "abc123" (string-append "abc" "123"))
#t
> (string=? "abc123" (string-append "abc" "123"))
#t

由于您正在使用字符串"p""l"进行比较,因此我应该能够在代码中用eq?替换string=?

(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
  (cond
    [(and (string=? (string-ref (first lis) 0) "p") (string=? (string-ref (first lis) 1) "l"))
     (cons (first lis) em)]
    [else
     (prefixes (rest lis) em)]))

但是,这揭示了第二个问题,只有在看到错误消息后才发现:

string=?: contract violation
  expected: string?
  given: #\y
  argument position: 1st
  other arguments...:
   "p"

string=?不起作用,因为它的第一个参数string-ref的结果是一个字符(如#\y),而不是字符串。要解决此问题,请使用char=?而不是string=?,并与字符#\p#\l(而不是字符串"p""l")进行比较。

(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
  (cond
    [(and (char=? (string-ref (first lis) 0) #\p) (char=? (string-ref (first lis) 1) #\l))
     (cons (first lis) em)]
    [else
     (prefixes (rest lis) em)]))