求助:编写匹配含...和_通配符的pattern与question的Scheme过程
实现Scheme通配符匹配过程
matching? 我来帮你搞定这个通配符匹配的问题,先梳理下你的需求和现有代码里的问题,再给出修正后的实现。
需求回顾
你需要的matching?过程要处理两种通配符:
_:匹配任意单个元素...:匹配零个或多个任意元素,核心是要能找到一个位置,让...之后的模式能和question的剩余部分匹配上
你的示例很清晰:
- 失败案例:
(matching? '(a b ... e) '(a b c d f))→#f(因为pattern最后是e,但question末尾没有e) - 成功案例:
(matching? '(a b ... e _ (x y)) '(a b 1 2 3 4 5 e card (x y)))→#t(...匹配1-5,_匹配card,最后(x y)完全对应)
现有代码的问题
你的代码里有几个关键问题:
- 递归调用语法错误:
(matching? (cdr pattern (cdr question)))这里cdr只能传一个参数,应该写成(matching? (cdr pattern) (cdr question)) ...的逻辑不对:当前代码遇到...只尝试跳过pattern的当前元素,没有处理...可以逐个吃掉question元素的情况- 长度判断逻辑僵化:比如
(= len1 len2)的条件限制了有...时的匹配(毕竟...会让长度不一样) - 边界条件不完善:比如question为空但pattern只剩
...时,应该返回#t(因为...可以匹配零个元素)
修正后的代码
(define matching? (lambda (pattern question) (cond ;; 情况1:pattern空了,question也必须空才匹配 ((null? pattern) (null? question)) ;; 情况2:question空了,只有pattern只剩...才匹配(...匹配零个元素) ((null? question) (and (not (null? pattern)) (eq? (car pattern) '...) (null? (cdr pattern)))) ;; 情况3:当前pattern元素是... ((eq? (car pattern) '...) (cond ;; 如果...是pattern最后一个元素,直接匹配剩余所有(包括零个) ((null? (cdr pattern)) #t) ;; 两种选择:要么用...吃掉当前question元素,要么结束...匹配后面的pattern (else (or (matching? pattern (cdr question)) (matching? (cdr pattern) question))))) ;; 情况4:当前是_,匹配单个任意元素,递归处理剩余部分 ((eq? (car pattern) '_) (matching? (cdr pattern) (cdr question))) ;; 情况5:普通元素,必须相等才继续递归 ((eq? (car pattern) (car question)) (matching? (cdr pattern) (cdr question))) ;; 其他情况:不匹配 (else #f))))
代码逻辑解释
咱们逐段看逻辑:
- 边界处理:当pattern耗尽时,只有question也耗尽才成功;当question耗尽时,只有pattern只剩
...才成功(因为...可以匹配零个元素) ...的核心逻辑:如果...是pattern最后一项,直接返回真(它能匹配question剩下的所有内容);否则有两种尝试方向:要么用...吃掉当前question元素(继续用原pattern匹配question的剩余部分),要么停止...的匹配,用pattern的剩余部分匹配当前question_的处理:简单直接,跳过当前pattern和question的元素,递归处理剩下的部分- 普通元素匹配:只有当pattern和question的当前元素相等时,才继续递归处理剩余部分
测试你的示例
- 测试失败案例:
(matching? '(a b ... e) '(a b c d f))→#f,因为当...尝试匹配到question末尾时,pattern还剩e,无法匹配,符合预期 - 测试成功案例:
(matching? '(a b ... e _ (x y)) '(a b 1 2 3 4 5 e card (x y)))→#t,完全符合你的需求
内容的提问来源于stack exchange,提问作者eon
相关产品推荐
相关产品推荐

