You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:编写匹配含...和_通配符的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)完全对应)

现有代码的问题

你的代码里有几个关键问题:

  1. 递归调用语法错误:(matching? (cdr pattern (cdr question)))这里cdr只能传一个参数,应该写成(matching? (cdr pattern) (cdr question))
  2. ...的逻辑不对:当前代码遇到...只尝试跳过pattern的当前元素,没有处理...可以逐个吃掉question元素的情况
  3. 长度判断逻辑僵化:比如(= len1 len2)的条件限制了有...时的匹配(毕竟...会让长度不一样)
  4. 边界条件不完善:比如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))))

代码逻辑解释

咱们逐段看逻辑:

  1. 边界处理:当pattern耗尽时,只有question也耗尽才成功;当question耗尽时,只有pattern只剩...才成功(因为...可以匹配零个元素)
  2. ...的核心逻辑:如果...是pattern最后一项,直接返回真(它能匹配question剩下的所有内容);否则有两种尝试方向:要么用...吃掉当前question元素(继续用原pattern匹配question的剩余部分),要么停止...的匹配,用pattern的剩余部分匹配当前question
  3. _的处理:简单直接,跳过当前pattern和question的元素,递归处理剩下的部分
  4. 普通元素匹配:只有当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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:27:29