0

我想获取两个字符串作为参数,并检查第一个字符串是否是第二个字符串的开头。我无法做到这一点,因为我不知道如何将字符串作为函数的参数。

(define starts-with( lambda (prefix str)
                  (define str2 (string->list (str)))
                  (define prefix2 (string->list (prefix)))
( cond ( (= (string-length(prefix2) 0) display "#t")
      ( (= car(prefix2) car(str2)) (starts-with (cdr(prefix2)cdr(str2) ) ) )
      ( display "#f")))))

Error:  application: not a procedure; expected a procedure that can be
 applied to arguments

给定:“ab”参数...:[无]

谁能解释一下我的错误是什么,以及总体上方案如何与列表或字符串一起使用..?我希望有:

 (starts-with "baz" "bazinga!") ;; "#t"
4

1 回答 1

1

问题不在于如何将字符串作为参数传递,问题在于……您首先必须了解 Scheme 的工作原理。括号在所有错误的地方,有些丢失,有些是不必要的,并且您调用程序的方式不正确。您的代码中有很多错误,需要完全重写:

(define (starts-with prefix str)
  (let loop ((prefix2 (string->list prefix)) ; convert strings to char lists 
             (str2 (string->list str)))      ; but do it only once at start
    (cond ((null? prefix2) #t) ; if the prefix is empty, we're done
          ((null? str2) #f)    ; if the string is empty, then it's #f
          ((equal? (car prefix2) (car str2)) ; if the chars are equal
           (loop (cdr prefix2) (cdr str2)))  ; then keep iterating
          (else #f))))                       ; otherwise it's #f

请注意原始实现中的以下错误:

  • 您必须将字符串转换为字符列表,但在开始递归之前只需一次。
  • 因为我们需要一个辅助过程,所以最好使用一个命名let它——它只是递归过程的语法糖,而不是真正的循环
  • 您错过了字符串短于前缀的情况
  • 您不应该display返回您打算返回的值,只需返回它们
  • 我们不能=用于比较字符,正确的方法是使用char=?or equal?,它更通用
  • a 的最后一个条件cond应该是else
  • 最后但同样重要的是,请记住,在 Scheme 中,函数是这样调用的:(f x)不是这样:f(x)此外,除非您打算将其作为函数调用,否则您无法放置()某些东西,这就是为什么 this:产生了错误(str)application: not a procedure; expected a procedure that can be applied to arguments
于 2017-01-03T16:27:25.170 回答