문제
현재 R5RS 체계 (PocketScheme에서)를 배우고 있으며 일부 변형의 구성표에 내장 된 함수를 사용할 수 있지만 전부는 아닙니다.
다시 말해 - 목록을 파괴적으로 변경합니다.
나는 실제 코드에 대한 답변 으로서는 목록을 함수 (또는 벡터 또는 문자열)로 전달할 수있는 프로세스를 이해 한 다음 돌연변이 할 수있는 프로세스를 이해하는 것만 큼 많은 관심이 없습니다.
예시:
(define (append! lst var)
(cons (lst var))
)
위와 같이 접근 방식을 사용하면 같은 일을해야합니다. (define list (append! foo (bar))
더 일반적인 것을 원합니다.
해결책
돌연변이는 허용되지만 계획에서 강력하게 낙담합니다. PLT는 심지어 제거하기까지했습니다 set-car!
그리고 set-cdr!
(그들은 그들과 "교체"했지만 set-mcar!
그리고 set-mcdr!
). 그러나 사양 append!
에 나타났다 SRFI-1. 이것 append!
당신과 조금 다릅니다. SRFI에서 구현 5월, 그러나 그렇지 않습니다 필수의 CONS 셀을 수정하여 목록을 추가합니다.
당신이 가고 싶다면 append!
그건 보장 추가 된 목록의 구조를 변경하려면 직접 작성해야 할 것입니다. 어렵지 않습니다 :
(define (my-append! a b)
(if (null? (cdr a))
(set-cdr! a b)
(my-append! (cdr a) b)))
정의를 간단하게 유지하려면 여기에서 오류가 확인되지 않지만 길이 1 이상을 1 이상으로 전달해야한다는 것은 분명합니다. a
, (바람직하게는) 목록 (모든 길이) b
. 이유 a
길이 1 이상이어야합니다 1은 당신이 할 수 없기 때문입니다. set-cdr!
빈 목록에.
이것이 어떻게 작동하는지에 관심이 있으므로 설명 할 수 있는지 확인하겠습니다. 기본적으로 우리가하고 싶은 것은 목록을 내려가는 것입니다. a
우리가 마지막에 도착할 때까지 cons
쌍입니다 (<last element> . null)
. 그래서 우리는 먼저 확인합니다 a
확인하여 이미 목록의 마지막 요소입니다. null
에서 cdr
. 그렇다면 우리는 사용합니다 set-cdr!
우리가 추가중인 목록으로 설정하고 우리는 끝났습니다. 그렇지 않다면, 우리는 전화해야합니다 my-append!
에 cdr
의 a
. 우리가 이것을 할 때마다 우리는 끝까지 가까워집니다. a
. 이것은 돌연변이 작업이기 때문에 우리는 아무것도 반환하지 않을 것이므로 수정 된 목록을 반환 값으로 형성하는 것에 대해 걱정할 필요가 없습니다.
다른 팁
이 주제에 대해 2-3 센트를 넣는 것보다 늦지 않는 것보다 늦지 않았습니다 ...
(1) 계획에서 파괴적인 절차를 사용하는 데 아무런 문제가 없습니다. 동안 수정중인 냄새에 대한 단일 참조가 있습니다. 예를 들어, 단일 참조를 통해 효율적으로 큰 목록을 구축하고 완료되면 다양한 참조자로부터 알려지고 언급 된 (이제는 수정되지 않은) 목록을 작성합니다.
(2) 나는 부속하다고 생각한다! 부록처럼 행동해야합니다. 그리고 추가하십시오! 많은 목록을 인수로 기대해야합니다. 각 목록이지만 마지막은 아마도 다음에 SET-CDR! 'D 일 것입니다.
(3) 위의 부록 정의! Mac LISP 및 Common LISP의 기본적으로 NCONC입니다. (및 다른 LISP).