2014-05-22 3 views
2
내가 구조체의 벡터에서 중복을 제거하기 위해 노력하고

을 :: 표준에서 제거하고이 중복이 구조체에 qieid에 의해 결정되는 경우 :분할 오류 벡터

struct infotable 
{ 
    int qieid; 
    int fid; 
    int valid; 
}; 

그리고 나는이 작업을 수행 할 수있는 하위 기능을 쓰기 :

void erase_duplicate(vector<infotable> &info) 
{ 
    vector<infotable>::iterator it0,it1; 

    for(it0 = info.begin();it0 != info.end()-1; it0++) 
    { 
    //it1 = find(qieidarray1.begin(),it0,*it0); 

    for(it1 = it0 +1;it1 != info.end(); it1++) 
    { 
     if((*it1).qieid == (*it0).qieid) 
     it1 = info.erase(it1); 
    } 
    } 
} 

그러나이 코드 조각에는 몇 가지 문제점이 있습니다. 벡터의 구조체 수가 적 으면 잘 동작합니다. 내가 벡터에서 3000 개 이상의 구조체에 대해이 때, 프로그램이 잘못하고 내가 가진 :

(11) 내 화면에 보여

세그먼트 오류. 메모리 액세스 문제이므로 벡터에 너무 많은 요소가 있기 때문에 만지지 말아야하는 곳에 액세스 할 수 있습니다. 더 나은 성능 (더 많은 요소를 실행)을 얻기 위해 코드를 향상시킬 수 있습니까?

+1

벡터 대신 집합을 사용 해본 적이 있습니까? 동일한 qieid를 가진 두 struct가 동일하다는 것을 세트에 알리기 위해 비교를 작성해야합니다. – Katu

+0

@katutxakurra 좋은 생각입니다! 나는 전에 세트를 사용한 적이 없다. 고마워! –

답변

4

또한, 특히 std::unique 그것을 할 <algorithm> 기능을 사용할 수 있습니다.

먼저 qieid으로 정렬 한 다음 unique을 사용하면 끝에있는 "삭제 된"요소를 이동하고 새로운 이터레이터를 반환합니다. 그러면이 요소를 사용하여 실제로 이러한 요소를 지울 수 있습니다.

std::sort(info.begin(), info.end(), [](const infotable& a, const infotable& b) { 
    return a.qieid < b.qieid; 
}); 
auto newIt = std::unique(info.begin(), info.end(), [](const infotable& a, const infotable& b) { 
    return a.qieid == b.qieid; 
}); 
info.erase(newIt, info.end()); 

이 O에서 실행 (N + N 로그) 것, 원래 솔루션 O를 가지고있는 반면 (N 2) 시간 복잡도. 개인적으로는 특히 표현이 풍부하고 코드가하는 일을보다 쉽게 ​​이해할 수 있으므로이 솔루션을 선호합니다.

: 당신의 컴파일러는 이미 C++ 14의 일반적인 람다를 지원하는 경우, 당신은 사용하여 더욱 표현을 단순화 할 수 있습니다 : [](const auto& a, const auto& b) { ... }

+0

+1, std :: unique, 항상 새로운 것을 배우는 것이 좋다. – Kiroxas

+0

@Kiroxas 네, 거기에 STL에 숨겨져있는 좋은 것들이있다. –

4

지우기를 사용하면 반복기가 무효화됩니다.

for(it1 = it0 +1;it1 != info.end();) 
{ 
    if((*it1).qieid == (*it0).qieid) 
     it1 = info.erase(it1); 
    else 
     it1++; 
} 
+0

많은 감사! 그게 정말 도움이 –

2

당신이 std::set 트릭과 중복을 제거 할 수 있습니다, 을 꽤 읽을 수있는, 쉽게 maintanable입니다 , 덜 효율적입니다.

std::vector<int> r = {14,26,58,56,26,14}; 

std::set<int> s(r.begin(),r.end()); 
r = std::vector<int>(s.begin(),s.end()); 

구조체와 함께 작동하려면 std :: 자신의 비교 함수를 설정해야합니다.

+0

- 그가 " 벡터 대신 도처에 설정 :) 어쨌든, 간결하고 멋진 솔루션 –