도메인 크기가 작고 (| D | ~ 20) 범위가 훨씬 더 큰 (| R | ~ 2 ^ 20) 모든 기능 집합 f : D-> R에 대해 분기 및 바운드 검색을 작성하려고합니다. ). 처음에는 다음 솔루션을 생각해 냈습니다.
(builder (domain range condlist partial-map)
(let ((passed? (check condlist partial-map)))
(cond
((not passed?) nil)
(domain (recur-on-first domain range condlist partial-map '()))
(t partial-map))))
(recur-on-first (domain range condlist partial-map ignored)
(cond
((null range) nil)
(t (let ((first-to-first
(builder (cdr domain)
(append ignored (cdr range))
condlist
(cons (cons (car domain) (car range)) partial-map))))
(or first-to-first
(recur-on-first domain
(cdr range)
condlist
partial-map
(cons (car range) ignored))))))))
여기서 condlist
함수 의 매개 변수 builder
는 솔루션이 충족해야하는 조건 목록입니다. check
조건 목록의 모든 요소가에 의해 위반되면 함수 는 nil을 반환합니다 partial-map
. 이 함수 recur-on-first
는 도메인의 첫 번째 요소를 범위의 첫 번째 요소에 할당하고 거기에서 솔루션을 작성하려고합니다. 이를 실패 recur-on-first
하면 도메인의 첫 번째 요소를 범위의 첫 번째 요소가 아닌 다른 요소에 지정하는 솔루션을 시도하고 구성 할 수 있습니다. 그러나 ignored
이러한 폐기 된 요소 (예 : 범위의 첫 번째 요소)를 도메인에있는 다른 요소의 이미지로 저장할 수 있는 목록을 유지 해야합니다.
이 솔루션에서 볼 수있는 두 가지 문제가 있습니다. 첫 번째는 목록 ignored
과 range
기능 recur-on-first
이 상당히 커서 append
값이 비싸다는 것입니다. 두 번째 문제는 솔루션의 재귀 깊이가 범위의 크기에 달려 있다는 것입니다.
그래서 이중 연결 목록을 사용하여 범위에 요소를 저장하는 다음 솔루션을 생각해 냈습니다. 기능 start
, next
및 end
이중 연결리스트를 반복하는 기능을 제공합니다.
(builder (domain range condlist &optional (partial-map nil))
(block builder
(let ((passed? (check condlist partial-map)))
(cond
((not passed?) nil)
(domain (let* ((cur (start range))
(prev (dbl-node-prev cur)))
(loop
(if (not (end cur))
(progn
(splice-out range cur)
(let ((sol (builder (cdr domain)
range
condlist
(cons (cons (car domain) (data cur)) partial-map))))
(splice-in range prev cur)
(if sol (return-from builder sol)))
(setq prev cur)
(setq cur (next cur)))
(return-from builder nil)))))
(t partial-map))))))
두 번째 솔루션의 런타임은 첫 번째 솔루션의 런타임보다 훨씬 낫습니다. append
첫 번째 솔루션 의 작업은 이중 연결 목록 안팎의 스 플라이 싱 요소로 대체되며 (이 작업은 일정한 시간 임) 재귀 깊이는 도메인의 크기에만 의존합니다. 그러나이 솔루션의 내 문제는 C
스타일 코드를 사용한다는 것 입니다. 제 질문은 이것입니다.
두 번째 솔루션만큼 효율적이지만 setf
s 및 가변 데이터 구조를 사용하지 않는 솔루션이 있습니까? 다시 말해,이 문제에 대한 효율적인 기능적 프로그래밍 솔루션이 있습니까?