【问题标题】:Longest chain of element in lisplisp中最长的元素链
【发布时间】:2020-07-13 20:45:33
【问题描述】:

语句:找到最长的字符链并返回它。 例如:输入:'(1 2 2 3 3 3 4 4 4 4 5 6 ) 输出:'(4 4 4 4)

问题:我可以设法识别列表中的所有不同组并进行比较,但无法让函数返回正确的子集列表。它只返回最后分析的组。

代码:

(define finalL (list))
(define (sameNum liste) 
  (if (or (null? liste) (null? (cdr liste)))
      ;; true
      '()
      ;; false
      (let ([lcdr (sameNum (cdr liste))]) 
        (if (eqv? (car liste) (car(cdr liste)) )
            ;; true
            (if (= (length liste) 2)
                ;; true
                (cons (car liste) (cons (car(cdr liste)) lcdr)) 
                ;; false
                (if (or (not(eqv? (car(cdr liste)) (car(cdr (cdr liste))) )) (null? (cdr liste)) )
                    (cons (car liste) (cons (car(cdr liste)) lcdr)) ;true
                    (cons (car liste) lcdr))) ; false
             ;; false
            (if (let ((x (length lcdr)) (y (length finalL))) (< x y))
                ;; true
                (crushL finalL lcdr)
                ;; false
                finalL)))))
;; crush L1 and replace by value of L2
(define (crushL L1 L2)
  (if (null? L1)
      ;; true
      (cons L2 L1)
      ;; false
      (crushL (cdr L1) L2)))

【问题讨论】:

    标签: scheme lisp


    【解决方案1】:

    诀窍是在您遍历列表时保留四件事:

    • 当前链(注意:您可以向后构建这些链,因为所有元素都相同!);
    • 多久了;
    • 你见过的最长的链条;
    • 多长时间了。

    然后您根据您正在查看的元素是否与当前链中的第一个元素相同(仍在构建相同的链)或是否(开始新链)以及如果您仍在构建同一条链,现在这条链是否最长。

    像这样:

    (define (longest-chain l)
      (let lc-loop ([tail l]
                    [current-length 0]
                    [current-chain '()]
                    [longest-length 0]
                    [longest-chain '()])
        (cond [(null? tail)
               ;; we're done: return the longest chain
               longest-chain]
              [(and (not (null? current-chain))
                    (eqv? (first tail) (first current-chain)))
               ;; building on a current chain
               (let ([chain (cons (first tail) current-chain)]
                     [chain-length (+ 1 current-length)])
                 (if (> chain-length longest-length)
                     ;; the current chain is now the longest
                     (lc-loop (rest tail)
                              chain-length chain
                              chain-length chain)
                     ;; it's not the longest yet
                     (lc-loop (rest tail)
                              chain-length chain
                              longest-length longest-chain)))]
              [else
               ;; starting a new chain
               (lc-loop (rest tail)
                        1 (list (first tail))
                        longest-length longest-chain)])))
    

    补充一点:如果有不止一个最长的链,这个函数返回哪一个?你怎么能改变它,让它做出另一个选择?甚至是随机的选择!


    注意上面版本的函数使用named let,这是Scheme中的标准构造。如果你不想使用它,你可以把它变成一个显式的函数:

    (define (longest-chain l)
      (define (lc-loop tail
                       current-length current-chain
                       longest-length longest-chain)
        (cond [(null? tail)
               ;; we're done: return the longest chain
               longest-chain]
              [(and (not (null? current-chain))
                    (eqv? (first tail) (first current-chain)))
               ;; building on a current chain
               (let ([chain (cons (first tail) current-chain)]
                     [chain-length (+ 1 current-length)])
                 (if (> chain-length longest-length)
                     ;; the current chain is now the longest
                     (lc-loop (rest tail)
                              chain-length chain
                              chain-length chain)
                     ;; it's not the longest yet
                     (lc-loop (rest tail)
                              chain-length chain
                              longest-length longest-chain)))]
              [else
               ;; starting a new chain
               (lc-loop (rest tail)
                        1 (list (first tail))
                        longest-length longest-chain)]))
      (lc-loop l 0 '() 0 '()))
    

    这完全等同于上面的版本。如果您对内部defines 不满意,那么您可以将lc-loop 转换为顶级定义。

    【讨论】:

    • 抱歉,我不明白循环中发生了什么。是的,我们遍历初始列表的其余部分,但什么是链长链,它有什么作用?我找不到有关如何解释此语法的文档
    • - 对于多个相同长度的最长链-> 函数返回找到的第一个。 - 要对另一个选择进行修改,需要进行 cond 函数,以便当列表为空时,我们通过比较长度来决定返回什么。 - 对于随机数,您将再次修改 cond 但可能会生成一个随机数并使用专用函数获取列表中的元素(不记得名称)
    • @Mat:我在最后添加了一点,展示了命名的let 是如何等效于本地函数定义的。
    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多