2012-08-06 5 views
3

다른 값의 4 개의 숫자 목록이 있습니다. 그 지점까지 모든 숫자의 합계를 설명하는 두 번째 목록이 있습니다 (list1 = [1,3,2,5], list2 = [1,4,6,11] 인 경우). 수십만 개의 목록을 얻는 방법으로 모든 번호를 추가 할 필요가 없습니다. 정보가 이미 저장되어 있습니다.끊임없이 변화하는 목록을 가장 효율적으로 분할하여 합계를 계산하는 방법은 무엇입니까?

list1의 인덱스 0에 새 번호를 삽입하고 숫자 2라고 말하면 list2의 다음 값을 모두 업데이트해야합니다. 매우 큰 목록의 경우, 이것은 (두 번째 목록의 목적을 무너 뜨리는) 매우 많은 시간을 필요로합니다.

그러나 목록의 처음 절반의 합계를 기록하면 해당 합계 (list2 = [1,4,2,7])를 기준으로 list2를 계속할 수 있습니다. 이제 index = 0에 숫자 2를 삽입하면 처음 두 값과 기록 된 중간 값만 업데이트하면됩니다. 100,000 개의 숫자 목록을 보려면 이렇게하면 50,000 개의 값만 업데이트하면됩니다.

또한 목록의 3 분의 1 또는 10,000 개의 숫자마다 값을 기록 할 수 있습니다. 또는 중간에서 절반을 기록 할 수 있습니다 (이진 정렬과 비슷합니다. 이제는 내가 속한 하위 목록 만 업데이트하거나보아야합니다. 영향을 미침).

질문 :이 목록을 관리하는 가장 효율적인 방법은 무엇이며 어떻게 결정합니까? 반 은요? 3 분의 1? 세 단계, 이전 단계를 반으로 줄인 단계?

[이것은 이론적 인 질문이 아니라 실용적인 질문입니다. List2는 텍스트/그래픽을 레이아웃하고 렌더링하기위한 오프셋을 제공합니다. 나무는 내가 작업하고있는 맥락에서 실용적이지 않을 것이다. 나는 하나의 목록을 다뤄야 만한다. 주어진 합계/오프셋에 대한 액세스가 필요합니다. 또한, 나는 그것을 명확하게 제시하는 데 어려움을 겪고있다. 질문을 명확하게하거나 설명을 요청하십시오.]

+1

어떤 종류의 나무 *를 원할 수도 있습니다. –

+0

감사합니다. 그러나 내가 왜 내 접근 방식을 선택했는지 분명하지 않을 수도 있다는 것을 이해하는 동안 '왜'는 내 질문에 거의 한계를 두지 않습니다. 문맥을 고려할 때 나무는 실행 가능한 옵션이 아닙니다. – Jeff

+0

목록에서 숫자를 삭제 하시겠습니까? 목록에 어떻게 접근합니까? 순서대로 트래버스하거나 인덱싱합니까? 목록에 얼마나 자주 새 번호를 삽입합니까? 얼마나 자주 목록에 액세스합니까? 목록의 숫자는 얼마나 큽니까? 목록은 얼마 동안 될 수 있습니까? – amdn

답변

0

배열 (Vector in C++)을 사용하여 합계를 포함하는 IndexSum을 호출합니다. 이전 합계를 뺀 값을 유추 할 수 있습니다. 합계에서). 배열은 간단하게 색인을 생성하고 순차적 액세스를 위해 잘 수행 할 수 있습니다. 배열은 다음 요소에 대한 포인터를 유지하지 않으므로 압축되고 프로세서 데이터 캐시에 잘 맞습니다. 정렬 된 배열 (벡터)에서 삽입 및 삭제를 유지하고 InsertDeleteAdjust라고 부르면 이진 검색으로 쉽게 액세스 할 수 있습니다. 이렇게하면 인덱스에 대한 IndexSum의 합계에 필요한 조정 내용을 추적 할 수 있습니다 범위. IndexSum을 InsertDeleteAdjust의 값으로 동 기적으로 업데이트하는 "가비지 수집"루틴을 주기적으로 실행할 수 있습니다. 이러한 주기적 "가비지 수집"의 대기 시간이 허용되지 않는 경우 비동기 스레드 및 잠금 등을 사용하면 더 좋아질 수 있습니다.

1

트리없이이 작업을 수행하는 간단한 방법은 기본 배열을 sqrt (N) 영역의 sqrt (N) 개 요소로 구성됩니다. 각 섹션에서 다루는 범위와 해당 범위의 요소 합계를 추적하십시오. 이제 원소 k까지의 합을 찾고 싶다면, 원소 k 앞에 오는 모든 sqrt (N) 크기의 범위에 대한 합계를 더하고 그 앞에 오는 원소 k의 범위에있는 원소들을 합산합니다. 이 두 가지는 모두 O (sqrt (N)) 시간이 걸리고 O (sqrt (N))의 합계입니다.

O (sqrt (N)) 목록과 O (sqrt (N)) 쿼리/수정이 필요하기 때문에 모든 작업, 삽입, 삭제 및 쿼리는 O)) 요소를 사용합니다.

가끔 구조를 개혁해야합니다. 이 작업을 수행 할 정확한시기는 당신에게 달려 있지만, 충분히 규칙적으로 수행해야합니다. 그렇지 않으면 O 작업 (sqrt (N)) 런타임을 해당 작업에 보관하지 않을 것입니다. 충분한 sqrt (N) 수정 (삽입 또는 삭제 만) 후에 목록을 완전히 다시 작성한 경우. O (N) 작업마다 O (sqrt (N)) 작업이 필요하며, 시간이 지남에 따라 상각되며 모든 작업에서 추가 O (sqrt (N)) 작업이 필요합니다.

관련 문제