2013-06-05 2 views
2

목록에서 마지막 요소를 찾아야하는 함수를 작성하기 시작했습니다. 내 생각은 search을 사용하여 지정된 기호의 발생 횟수를 계산하여 반환하는 것이 었습니다. 그런 다음 요소를 제거하는 removeLast에 카운트를 전달합니다. 그런 다음 기본 케이스를 용이하게하기 위해 카운트를 removeLast으로 감소시킵니다. 내가 보았던 것에서는 set!을 사용하는 것이 좋지 않습니다. 기호의 마지막 발생을 "기억"하는 더 좋고/더 우아한 방법이 있습니까? ((set! count (sub1 count))(cons (car lis)(removeLast symbol (cdr lis) count)))) 같이 코드를 실행목록에서 지정된 요소의 마지막 항목 찾기 및 제거 [racket]

(define (lastLess lis symbol) 
    (define count 0) 
    (set! count (search symbol lis count)) 
    (removeLast symbol lis count) 
) 

(define (search symbol lis count) 
    (cond ((null? lis) count) 
    ((eq? symbol (car lis)) (+ count (add1 (search symbol (cdr lis) count)))) 
    ((pair? (car lis))(+ count(+ 0 (search symbol (car lis) count)))) 
    (else (+ count(+ 0 (search symbol (cdr lis) count)))) 
    ) 
) 

(define (removeLast symbol lis count) 
    (cond ((null? lis) '()) 
    ((eq? count 0) (cdr lis)) 
    ((eq? symbol (car lis)) ((set! count (sub1 count)) 
          (cons (car lis)(removeLast symbol (cdr lis) count)) 
          ) 
          ) 
    ((pair? (car lis)) (removeLast symbol (car lis) count)) 
    (else (cons (car lis) (removeLast symbol (cdr lis) count))) 
    ) 
) 

오류가 발생합니다 :

application: not a procedure; expected a procedure that can be applied to arguments given: # arguments...: '(e)

편집 : 이것은 reverse의이 허용되지 않도록 중복 클래스에 대한 할당하고, 나는 둥지 목록 고려해야합니다 .

답변

2

오류는 cond 절에서 발생합니다. 당신은 주위에 여분의 괄호가 있습니다 (set! count ...).

귀하의 문제는 귀하의 집착에 집착입니다! 이 :

(define (lastLess lis symbol) 
    (define count 0) 
    (set! count (search symbol lis count)) 
    (removeLast symbol lis count)) 

(define (lastLess lis symbol) 
    (let ((count (search symbol lis 0))) 
    (if (< 0 count) ; noe or more occurences 
     (removeLast symbol lis count) 
     lis))) 

검색 절차가 시작됩니다

결과 더 이상의 위치를 ​​사용할 때 좋은

(define (lastLess lis symbol) 
    (removeLast symbol lis (search symbol lis 0))) 

또는 당신이 원하는 임무를 수행 할 수 있었다 목록에있는리스트를리스트없이 끝내지 않는다. 각각은 (a b (c d b) a b)에있다. 프로 시저는 2가 아니라 3을 반환 할 것이다. + 인자의 수는 제한이 없다. 그래서 당신은 그것들을 중첩 할 필요가 없습니다. 시도해보십시오.

(define (search symbol lis count) 
    (cond ((null? lis) count) 
    ((eq? symbol (car lis)) (search symbol (cdr lis) (add1 count))) 
    ((pair? (car lis)) (search symbol (cdr lis) 
           (search symbol (car lis) count))) 
    (else (search symbol (cdr lis) count)))) 

페어가 처리되는 방식에 유의하십시오. 이제 count가 0 일 때 심볼이 일치하고 카운트가 1 일 때 removeLast는 무엇이든 건너 뛰지 않아야합니다.

행운을 비네!

+0

나는 당신이 말하는 것을보고 있습니다. 이것은 도움이된다. 고마워. – BrianM

3

이 작업을 위해 기본 제공 절차를 사용해야합니다. 특히 remove이 때문에 마지막 요소를 제거 symbol 같다 lis 요소 목록을 반전하는 간단한 문제이다 삭제 통지 :

(define (lastLess lis symbol) 
    (reverse (remove symbol (reverse lis)))) 

(lastLess '(1 2 3 4 5 1) 1) 
=> '(1 2 3 4 5) 

상기 용액은 필요로하지 않는다 전혀 의심 스럽지만 추천하지 않는 set!을 사용하십시오. 목록을 변경하는 문제를 해결할 수는 있지만 Scheme에서 기능적 솔루션을 선호합니다.

물론 더 효율적인 솔루션이 작성 될 수 있습니다. 목록을 한 번만 탐색하는 솔루션이 있지만 실제로 이러한 솔루션의 복잡성이 추가적으로 필요합니까? 고성능이 그렇게 중요합니까? 대답이 '아니요'라면 간단하고 명확한 해결책을 고수하십시오.

+0

이제 중첩 된 목록도 고려해야할까요? 수업 시간에 교수님과 교수님은 "여분의 반전은 받아 들일 수 없습니다."라고 말씀하셨습니다. 귀하의 의견에 감사드립니다. – BrianM

+1

이 답변은 편집 이전에 게시되었으며, 실제로는 중첩 목록을 고려하지 않았으며 실제로 중복 된 (?) 역 수행을 수행합니다. 편집을 마치면 완전히 다른 짐승이됩니다. 죄송합니다. 지금 대답을 찾을 수 없습니다. 자정이 지나서 여기 주위에 있습니다. :) –

0

이것은 여전히 ​​집합을 사용하지만 집합이 foldr로 인수로 전달하는 익명의 함수를 닫는 데 사용되므로 더 논리적 인 해결책입니다.After가 첫 번째 일치를 찾으면 (꼬리에서 일한다는 것을 기억하십시오.) foldr은 목록의 끝 부분에서 작동하기 때문에 별도의 탐색이 필요하지 않으므로 make-remover는 기능 프로세스입니다 (한 입력은 항상 같은 출력으로 매핑됩니다) 그러나 출력은 함수가 아닙니다만, 한 번만 사용하고 버려야하므로 문제가 많지 않습니다 (어쨌든 일대일 매핑을하지 않아도됩니다)

(define (remove-last x L) 
(let ((proc (make-remover x))) 
    (foldr proc '() L))) 


(define (make-remover removee) 
(let ((active? #t)) 
    (lambda (x y) 
    (cond ((not active?) (cons x y)) 
     ((eq? x removee) (begin (set! active? #f) y)) 
     (else (cons x y)))))) 

이 (중첩 된 목록에 대한 작업) 나무를 통과하지 않습니다하지만 그들에게 절차를 적용하기 전에 하위 목록에 foldr하는 foldr 트리에 foldr을 수정하기 어려운 끔찍한 안된다.