【问题标题】:scheme recursive function list overrides方案递归函数列表覆盖
【发布时间】:2017-05-18 12:05:43
【问题描述】:

我正在尝试做一个递归函数,它获取一个字符串-整数对列表+一个名为前缀的字符串,并使用名为“starts-with”的函数总结所有与前缀匹配的整数。 问题是,我永远无法让列表继续前进,它在开始时卡住,然后程序崩溃。

(define (sum-of-pairs-start-with prefix ls)
    ( let*(  (prefix2 (string->list prefix))
          (str2 (string->list (car (car ls)))))
(cond((null? str2) 0)   
     ( (starts-with prefix (car(car ls))) 
       (+  cdr(car ls) (sum-of-pairs-start-with prefix (cdr ls))) ) 
     (else sum-of-pairs-start-with prefix (cdr ls))) ) )     

我使用输入:

(sum-of-pairs-start-with "a" (list (cons "a" 1) (cons "b" 2) (cons "aa" 33) (cons "ca" 4))) ;; =34

但是一旦我到达列表中的第二对(“b”2),它就会按预期进入 else 条件,但随后 ls 会返回一行到原点(使用前一个值)而不是前进到下一个值(“aa”33)。 我是新来的计划,我不明白为什么会这样,这令人沮丧

【问题讨论】:

  • 首先,去掉所有的语法错误。
  • 哪些语法错误?球拍的编译器没有提到任何..
  • 嗯,有语法错误,还有语法错误。比较这两个表达式:(list (+ 1 2))(list + 1 2)。编译器或解释器不会抱怨第二个,因为它是一个完全合法的表达式。这也几乎肯定不是你想要的。
  • 您如何看待它“备份”?我在球拍中得到“+:违反合同......”。 (顺便说一句,正如预期的那样;您正在尝试添加 cdr(car ls) 和递归结果。)
  • 我在 Debug 模式下看到它,它在 "else" 行,然后又回到它上面的行

标签: list recursion scheme racket


【解决方案1】:

您只需调用我们之前定义的starts-with 过程(让它负责将字符串转换为字符列表),并修复所有语法问题

(define (sum-of-pairs-start-with prefix ls)
  (cond ((null? ls) 0)   
        ((starts-with prefix (car (car ls)))
         (+ (cdr (car ls)) (sum-of-pairs-start-with prefix (cdr ls))))
        (else (sum-of-pairs-start-with prefix (cdr ls)))))

再一次,您在调用程序时遇到了麻烦。例如,这些 sn-ps 是错误的:

cdr(car ls)
(else sum-of-pairs-start-with prefix (cdr ls))

请拿起一本关于 Scheme 的书并练习基本语法,记住过程不是这样调用的:f(x),正确的方法是(f x)。另外,要注意代码缩进的正确方式,按照约定会更容易发现错误。

【讨论】:

  • 洛佩兹相信我正在尽我所能,在 youtube 和其他东西上观看它,但我就是不明白。我已经自己解决了这个问题,但我还有很多问题
  • @mooly 我知道你在努力,我赞扬你的努力 :-),但在此之前花更多时间熟悉基本语法并解决更简单的问题是个好主意应对更艰巨的挑战。一些不错的入门书籍:“The Little Schemer”、“How to Design Programs”。
  • @mooly How to Design ProgramsStructure and Interpretation of Computer Programs(不太适合初学者,但非常好)都可以在线免费获得。书籍比 youtube 好。
【解决方案2】:

以下是使用更高功能的解决方案:

(define (sum-of-pairs-start-with prefix ls)
  (apply +
         (map cdr
              (filter (λ (x) (starts-with prefix (car x)))
                      ls))))

它过滤掉那些在第一项中具有前缀的子列表,然后从每个子列表中获取第二项(cdr),最后对所有子列表应用添加函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多