Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 递归子列表?功能_Scheme - Fatal编程技术网

Scheme 递归子列表?功能

Scheme 递归子列表?功能,scheme,Scheme,我似乎不知道如何编写一个正确的uscheme(mitscheme的派生)函数,该函数将返回布尔值,无论列表是否包含较小的列表 这是我写的 (define sublist? (xs ys) (if (= xs '()) #t (if (= ys '()) #f (if (= (car xs) (car ys)) (sublist? (cdr xs) (cdr ys))

我似乎不知道如何编写一个正确的uscheme(mitscheme的派生)函数,该函数将返回布尔值,无论列表是否包含较小的列表

这是我写的

(define sublist? (xs ys)
    (if (= xs '())
        #t
        (if (= ys '())
            #f
            (if (= (car xs) (car ys))
                (sublist? (cdr xs) (cdr ys))
                (sublist? xs (cdr ys))
            )
        )
    )
)
除了这一个测试用例外,它通过了我的大多数测试用例

(sublist? '(a b c) '(1 2 a 3 b 4 c 5 6))
;; this returns true while it's supposed to return false
测试用例要求子列表是连续的,中间没有随机元素


我有点纠结于如何纠正这个问题。还有其他人有想法吗

问题在于,您的算法过于急切,一旦找到两个相等的元素,它会立即丢弃该元素并继续检查。事实上,仅仅找到两个相等的元素是不够的,因为如果算法发现不完全匹配,它可能不得不回溯

表示这种算法的最简单方法是使用一个helper函数,该函数确定子列表是否在列表中的给定位置匹配。然后,
子列表?
函数将遍历较大列表中的每个位置以查找匹配项

以下是我的实现:

(define (sublist? xs ys)
  (define (sublist-equal? xs ys)
    (cond
      ((null? xs) #t)
      ((null? ys) #f)
      ((equal? (car xs) (car ys))
       (sublist-equal? (cdr xs) (cdr ys)))
      (else #f)))
  (cond
    ((null? xs) #t)
    ((null? ys) #f)
    ((sublist-equal? xs ys) #t)
    (else (sublist? xs (cdr ys)))))
注意内部的
子列表equal?
helper函数

我还使用
cond
而不是嵌套的
if
表达式,因为在这种情况下应该真正使用
cond
来表示这种逻辑。此外,我使用
equal?
而不是
=
,因为它是我所知道的大多数方案,
=
用于数值比较(我不知道您的可能不同)。

这是我的版本“没有辅助函数”。但它确实使用了两个嵌套循环:

(define (sublist? needle haystack)
  (if (null? needle)
      #t
      (let ((first (car needle)))
        (let outer ((cur haystack))
          (define (next)
            (outer (cdr cur)))
          (cond ((null? cur) #f)
                ((eqv? (car cur) first)
                 (let inner ((lhs (cdr needle))
                             (rhs (cdr cur)))
                   (cond ((null? lhs) #t)
                         ((null? rhs) (next))
                         ((eqv? (car lhs) (car rhs))
                          (inner (cdr lhs) (cdr rhs)))
                         (else (next)))))
                (else (next)))))))

在没有辅助函数的情况下可以这样做吗?这非常有效。我希望有一个没有助手功能的版本。谢谢你的帮助!很好的代码,但我的作业说它必须是递归的,而不是迭代的。从技术上讲,你的版本也是迭代的(Alexis的版本也是如此)。;-)但我会看看我能做些什么。
(define sublist? (xs ys)
  (cond ((= xs '()) #t)  ;;cond easier to read than 
        ((= ys '()) #f)  ;;nested if statements
        ((and (= (car xs) (car ys)) 
 ;;need to check for more than singleton match
              (or (null? (cdr xs))
                  (and (not (null? (cdr ys)))
                       (= (cadr xs) (cadr ys))
                       (sublist? (cdr xs) (cdr ys)))))) ;not tail call
  ;;this cond clause has no second part, 
  ;;the first will return #t or #f
  ;;will backtrack if #f is propagated up the stack.
         (else (sublist? xs (cdr ys)))) ; tail call