2013-07-17 4 views
1

그래서 서로 다른 형식과 구조로 조정해야하는 두 가지 목록이 있습니다. 기본적으로 집합 B는 집합 A에있는 내용과 일치해야하지만 집합 B에있는 기존 항목의 상태를 보존하고 집합 A에있는 항목으로 덮어 쓰지는 않습니다.두 목록을 조정하십시오.

참고로 목록은 실제로 목록을 의미하지 않습니다 . "목록"은 직선 배열에서지도에 이르는 두 가지 형태로 제공됩니다. 모두 표준 요소 반복자를 사용하여 요소에 액세스합니다. 나는 일반적으로 처리

방법이 작동하고 내가 그것을 수행하는 생각할 수있는 유일한 방법입니다

for item in listA 
    if listB contains item 
    mark item in list B as visited 
    else 
    add item to list b 

for item in listB 
    if visited is true 
     continue 
    else 
     add item to removeList 

for item in removeList 
    remove item from list B 

...과 같이합니다. 나는 반복해야 할 반복을 얼마나 많이 반복하는지에 대해 싫어한다. 그러나 반복자를 사용하고 있기 때문에 목록을 검사하는 동안 목록에서 아무 것도 제거 할 수 없으며 목록에서 세 번째 제거 목록에 추가해야합니다.

잠정적 인 답은 속도와 메모리 사용 공간이 코드를 작성하는 것이 얼마나 쉬운지를 명심하십시오.

내 질문은 정말이까지 내려 간다. 내가 생각할 수없는 더 좋은 방법이 있는가?

나는 어떤 해결책이 아마도 언어 불가 지론이 될 것이라고 생각하지만, 나는 C++/C FWIW에있다.

감사합니다.

+0

"contains"는 상수 또는 적어도 시간 연산입니다. 방문자 B로 표시된 항목을 즉시 방문한 적이 없다고 표기하는 대신에 제거 할 수없는 이유는 무엇입니까? 약간의 작업만으로, 반복자가이 권한을 처리 할 수 ​​있다고 확신합니까? –

+0

그건 내 주요 관심사 였어. STL 반복자에 대한 필자의 이해는 반복되는 동안 기본 데이터 구조를 (제거 또는 삽입과 관련하여) 만질 수 없다는 것이 었습니다. 내가 생각할 수있는 모든 "수정"은 제거 목록을 반복하는 것보다 비용이 많이 들며 일반적으로 매우 작습니다. –

+0

STL 컨테이너에서 "제거"를 호출하면 가로 채기를 계속할 수있는 새로운 반복기가 제공됩니다. 상황이 가속화되는지 확인해보십시오. –

답변

0

여기보다 효율적으로 할 수 그것을 할 수있는 또 다른 방법 :

removeList = listB 

for item in listA 
    if listB contains item 
    remove item from removeList 
    else 
    add item to listB 

for item in removeList 
    remove item from listB 

그래서 그 대신 아무것도에서 removeList을 구축, 그것은 모든 것을 시작합니다 후 제거 항목이 있습니다.

또한 실제 항목이 아닌 removeList가 색인을 저장함으로써 더 효율적으로 만들 수 있습니다. 항목이 초기 루프에서 listB의 끝에 추가되고 항목이 역순으로 제거되는 한, 색인은 여전히 ​​유효해야합니다.

removeList을 유지할 부울 배열로 대체하면 사실 더 간단합니다.

initialise all itemsToKeep to false 
savedListLength = length of listB 

for item in listA 
    offset = find item in listB 
    if found 
    mark itemsToKeep[offset] as true 
    else 
    add item to listB 

for offset from savedListLength-1 down to 0 
    if itemsToKeep[offset] is false 
    remove the offset from listB 

이 처음 removeList에 아무것도 복사 할 필요가 피할 수 : 그래서 알고리즘은 다음과 같이된다. itemsToKeep 배열의 비용은 분명히 알고리즘의 특정 항목을 추적하는 데 사용하는 것보다 나쁘지 않습니다.

어느 정도까지는 가장 적합한 알고리즘이 목록 (즉, 벡터 또는 링크 된 목록 등)의 형태에 따라 다를 수 있습니다.하지만 내 접근 방식이 어느 쪽이든 더 효과적 일 수 있다고 생각합니다.

+0

내가 가지고있는 것보다 그게 더 낫다. 목록 b를 removelist로 복사하면 목록 B가 반복 될 것이므로 A와 반복 목록을 반복해야하므로 모든 반복자는 여전히 동일한 반복 횟수를보고 있습니다. –

+0

@MotieMediator 그게 중요한 점이지만, 코드 줄의 관점에서 보면 더 깔끔합니다. 그리고 그것은 또한 플러스라고 생각하는 것을 채점 할 필요가 없습니다. –

+0

@MotieMediator 또한 removeList를 없애기 위해 알고리즘을 수정하는 방법을 보여주는 답을 업데이트했습니다. –

관련 문제