簡體   English   中英

消除球拍列表中最后一次出現的元素

[英]eliminate the last occurrence of an element in a list in racket

我只是想知道,我可以在球拍中創建一個函數來消除列表中元素的最后一次出現嗎,例如,

>(last-without   '(a b  a  (c e) d)    'e)  =  (a b a (c) d)
>(last-without   '(p q  p (r p) q e p r)   'p) = (p q  p (r p) q e r)

也可以通過泛化可用於建立最后一次無遞歸調用的內置成員無需使用冗余反向來定義嵌套列表的成員資格測試來完成此操作。

(define (last-without list el)
  (define (remove-last-rec lst)
    (cond ((null? lst) '())
          ((equal? (car lst) el) (cdr lst))
          ; Corner case below, if car is a list, we also have to check it for occurences of el
          ((list? (car lst)) (let* ((nested (car lst))
                                    (rest (cdr lst))
                                    (nested-res (last-without nested el)))
                               (if (equal? nested nested-res)
                                   (cons nested-res (remove-last-rec rest)); el did not occur in nested list
                                   (cons nested-res rest)))) ; We did removed it, not remove it from cdr anymore, instead just cons the unchanged cdr.
          (else (cons (car lst) (remove-last-rec (cdr lst))))))

  (reverse ; Reverse filtered list back to original order
   (remove-last-rec 
    (reverse list))))

您會注意到(car lst)是列表的特殊情況。 如果它是一個列表,我們必須檢查它是否存在el

重要的是,我們在該列表中調用了last-without而不是remove-last-rec 這是因為嵌套列表未通過開始調用中的原始reverse (reverse (remove-last-rec (reverse list)))

如果您調用remove-last-rec ,則嵌套列表的順序在結果中將是錯誤的。 我建議您自己嘗試一下(錯誤地調用remove-last-rec ),嘗試提出您認為可能會失敗的列表非常有幫助。

如果找不到任何內容,請嘗試此。 它不會輸出您期望的結果。

(last-without '(a (b c a c) b) 'c)

編輯 :極端情況需要進行顯式測試以檢查(last-without nested el)返回相同的嵌套列表。 如果否,最后一次出現el嵌套表nested過濾出來,我們並不需要過濾掉的最后一次出現elrest了。

這是一個解決方案:

(define (last-without lst el)
  (define (aux lst)  ; returns two values: removed and result
    (if (null? lst)
        (values #f '())
        (let-values (((removed result) (aux (cdr lst))))
                (if removed
                    (values removed (cons (car lst) result))
                    (cond ((equal? (car lst) el) (values #t result))
                          ((list? (car lst))
                           (let-values (((removed-from-car result-of-car) (aux (car lst))))
                             (values removed-from-car (cons result-of-car result))))
                          (else (values #f (cons (car lst) result))))))))
  (let-values (((removed result) (aux lst)))
    result))

輔助函數執行元素的刪除並返回兩個值:一個布爾值(如果元素已刪除,則為#t和結果列表。 因此,在檢查列表不為空之后,它將自身應用於列表的其余部分,並返回兩個值。 如果removed#t ,則無需執行其他任何操作,並且將重建列表。 否則,該函數仍必須刪除該元素,因此它會檢查它是否等於lst的第一個元素,並在這種情況下將其刪除;否則,如果第一個元素是列表,則對其進行調用。

最后請注意,標題在某種程度上具有誤導性:該函數不會從列表中刪除最后一個el元素,而是從樹中刪除最右邊的el元素。

嘗試

(define (remove-last xs)
  (reverse (remove-first (reverse xs) x)))

其中(remove-first xs x)將刪除(remove-first xs x)中第一次出現的x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM