2016-10-12 4 views
1

저는 내장 함수와 동일한 코드를 작성하는 것을 좋아합니다. 항상 나를위한 훌륭한 운동입니다.Racket - 내장 멤버 함수 만들기

라켓에는 "member"라는 bult-in 함수가 있습니다.이 함수는 특정 요소가 목록 안에 있는지 확인합니다. true이면 함수는 나머지를 반환합니다./cdr o false이면 함수는 #f를 반환합니다. 예 : 나는 멋진 툴 트레이스 함께 사용하려고 할 때, 나는 부분적으로 성공 오전,

(require racket/trace) 

(define (member-mine lista num) 
    (cond ((equal? (car lista) num) (cdr lista)) 
     ((equal? (car lista) '()) #f) 
     (else (member-mine (cdr lista) num)))) 

(define small-list (list 1 2 3 4 5 6 7 8)) 

(trace member-mine) 

그리고 :

> (member 2 (list 1 2 3 4)) 
'(2 3 4) 

> (member 9 (list 1 2 3 4)) 
#f 

나는 다음과 같은 코드를했다.

콜링 :

(member-mine small-list 1) 

결과 :

>(member-mine '(1 2 3 4 5 6 7 8) 1) 
<'(2 3 4 5 6 7 8) 

콜링 :

(member-mine small-list 8) 

결과 :

>(member-mine '(1 2 3 4 5 6 7 8) 8) 
>(member-mine '(2 3 4 5 6 7 8) 8) 
>(member-mine '(3 4 5 6 7 8) 8) 
>(member-mine '(4 5 6 7 8) 8) 
>(member-mine '(5 6 7 8) 8) 
>(member-mine '(6 7 8) 8) 
>(member-mine '(7 8) 8) 
>(member-mine '(8) 8) 
<'() 

문제는 주어진 목록에없는 요소를 호출 할 때입니다. 출력은 #F되어야한다 : 나는 빈 다루는 관리 어떻게

>(member-mine '(1 2 3 4 5 6 7 8) 9) 
>(member-mine '(2 3 4 5 6 7 8) 9) 
>(member-mine '(3 4 5 6 7 8) 9) 
>(member-mine '(4 5 6 7 8) 9) 
>(member-mine '(5 6 7 8) 9) 
>(member-mine '(6 7 8) 9) 
>(member-mine '(7 8) 9) 
>(member-mine '(8) 9) 
>(member-mine '() 9) 
. . car: contract violation 
    expected: pair? 
    given: '() 

:

반환
(member-mine small-list 9) 

오류인가?

답변

3

코드에 몇 가지 문제가 있습니다. 첫 번째 관찰에서 목록이 마지막이 아니라 처음으로 오도록 계약을 전환했습니다.

요소 중 하나가 목록 자체가 아닌 빈 목록인지 확인하는 것처럼 보입니다. 따라서 귀하의 member이 경우 #f으로 종료합니다 :

(member-mine '(() 1 2 3 4 5 6 7 8) 1) ; ==> #f 

전체 인수가 null? ( empty?) 인 경우 따라서 귀하의 회원 확인해야하거나 pair?가 아니라면 아마도 확인합니다. 그런 다음 #f으로 평가됩니다.

첫 번째 요소가 검색과 일치하는 경우 원본 member은 일치 항목이 첫 번째 요소로 전체 인수로 평가되고 코드에는 cdr이 아닙니다.

0

빈칸을 조건부의 첫 번째 분기로 이동하십시오. 마지막 재귀 호출에서 빈 목록이 함수에 전달되면 목록이 비어 있기 때문에 수행 할 수없는 목록의 car을 요청합니다. 빈 주먹을 넣으면 함수는 car에 도달하기 전에 #f으로 종료해야합니다.

+0

감사합니다. (cond ((공백? lista) #f) (같은? cdr lista) num)))) 빈을 처리 할 다른 방법이 있습니까? –

+0

확실하지 않습니다. 내 지식에 비어있는 경우는 재귀 함수의 기본 경우이기 때문에 적절한 종료를 보장하는 유일한 방법입니다. – VergeA

0

빈 목록을 확인하는 또 다른 방법은 길이를 확인하는 것입니다 :

(define (member-mine lista num) 
    (cond 
    ((equal? (length lista) 0) #f) ; '=' can also be used instead of 'equal?' 
    ((equal? (car lista) num) (cdr lista)) 
    (else (member-mine (cdr lista) num)))) 

(define small-list (list 1 2 3 4 5 6 7 8)) 

(member-mine small-list 9) 

출력 :

#f 

그러나 적절한 방법은 다음과 같습니다

(empty? lista) or (null? lista)