문제

최근에,나는 어떤 사람들은 언급 할 std::list::size() 선형 복잡합니다.
에 따라 , 이 사실 구현 방식에 따라 다릅 표준으로 말하지 않는 것은 복잡고 있다.
이 블로그 항목에 말합니다:

실제로,그에 따라 달라집 STL 당신 이 사용하고 있습니다.Microsoft Visual Studio V6 를 구현하는 크기(가로){return(_Size);}반면 gcc(적어도 versions 3.3.2 및 4.1.0)할로{return std::리(begin(),end());}의 처음에는 일정한 속도로,두 번째 는 o(N)속도

  1. 그래서 나는 대한 VC++군중 size() 는 일정한 복잡성으로 Dinkumware 아마 없이 변경되었다는 사실이기 때문 VC6.나는가?
  2. 어떻게 현재 gcc?면 그것은 정말 O(n),왜 개발자는 그렇게 하도록 선택?
도움이 되었습니까?

해결책

Pre-C++응답 11

당신이 올바른 표준하지 않는 것의 복잡성 리스트::크기()어야-그러나,그것은 않는 것이 좋습니다"해야 일정한 복잡성을"(주 표 65).

여기 재미있는 기사를 하워드에 의해 Hinnant 이유를 설명하는 어떤 사람들은 생각 리스트::크기(가)있어야 O(N)복잡성(기본적으로 믿기 때문에 O(1)리스트::크기()목록을 만든다::splice()O(N)복잡성)과 이유 O(1)리스트::크기()는 좋은 아이디어(에서는 저자의 의견):

나는 생각한 주요 포인트에서 종이습니다:

  • 거기에 몇 가지 상황을 유지하는 내부 계산서 list::size() 할 수 있습 O(1)의 원인이 결합하는 작업이 될형
  • 아마 많은 상황이 사람이 인식하지 못할 수 있습의 부정적인 효과가 일어날 수 있기 때문에 그들이 부르는 O(N) size() (과 같은 자신의 한 예가 list::size() 이라고 하는 동안 잠금을 보유하).
  • 대신 허가 size() 수 O(N),의 관심사안에도 놀라운',표준 필요한 모든 컨테이너를 구현하는 size() 그것을 구현하기 위해서는 O(1)패션이다.는 경우에는 컨테이너 할 수 없습니다,그것을 구현하지 않아야 합 size() 다.이 경우에는 사용자의 컨테이너가 될 것입니다는 것을 알 size() 를 사용할 수 없는 경우 그들은 여전히 원하는 또는 필요를 얻을 수 컨테이너의 요소들 수 있는 여전히 사용 container::distance( begin(), end()) 을 얻을 수 있는 값들입니다-그러나 그것들이 여러분히 알고 있는 그 O(N)작업입니다.

내가 생각하는 경향이와 대부분의 동의 자신의 논리로.그러나,좋아하지 않는 그의 제안을 splice() 오버로드.을 통과하는 n 는 동일해야합 distance( first, last) 올바른 행동을 보인에 대한 조리법과 같은 진단하기 어렵습니다.

나는 확실하지 않다 무엇을 해야 하나 할 수 있는 앞으로 어떤 변화에 상당한 영향을 미치는 기존의 코드입니다.하지만 그대로,나는 생각하는 기존의 코드가 이미 영향을 받는 행동될 수 있는 오히려 상당히 다른 하나에서 구현하는 다른 뭔가를 해야 하는 잘 정의됩니다.어쩌면 onebyone 의 코멘트에 대해 크기는'캐싱'표시 알려진/알 수 없는 작동 할 수 있는지 당신은 상각 O(1)인 행동만을 얻을 시간 O(N)동작은 경고 목록은 수정 일부에 의해 결합()작업입니다.좋은 것은 이것에 대해 수행할 수 있습 구현 자에 의해 오늘 없이 변화하는 표준(지 않는 한 나는 뭔가가).

내가 알기로는,C++0x 변경되지 않은 아무것도 지역에 있습니다.

다른 팁

C ++ 11에서는 필요합니다 어느 표준 컨테이너 .size() "상수"복잡성 (O (1))에서 작동이 완료되어야합니다. (표 96 - 컨테이너 요구 사항). 이전에 C ++ 03 .size() ~해야 한다 일정한 복잡성이 있지만 필요하지 않습니다 ( std :: string size () a o (1) 작동입니까?).

표준 변경은 다음과 같이 소개됩니다 N2923 : size ()의 복잡성 지정 (개정 1).

그러나의 구현 .size() libstdc ++에서 여전히 GCC의 O (n) 알고리즘을 최대 4.8로 사용합니다.

  /**  Returns the number of elements in the %list.  */
  size_type
  size() const _GLIBCXX_NOEXCEPT
  { return std::distance(begin(), end()); }

또한보십시오 C ++ 11에서 STD :: 목록이 더 큰 이유는 무엇입니까? 왜 이런 식으로 유지되는지 상세하게.

업데이트: std::list::size() ~이다 올바르게 o (1) GCC를 사용할 때 5.0 C ++ 11 모드 (또는 위)에서.


그건 그렇고, .size() libc ++에서 올바르게 O (1) :

_LIBCPP_INLINE_VISIBILITY
size_type size() const _NOEXCEPT     {return base::__sz();}

...

__compressed_pair<size_type, __node_allocator> __size_alloc_;

_LIBCPP_INLINE_VISIBILITY
const size_type& __sz() const _NOEXCEPT
    {return __size_alloc_.first();}

GCC 3.4의 목록 :: 크기를 살펴 봐야 했으므로 다음을 말할 수 있습니다.

  1. std :: 거리 (머리, 꼬리)를 사용합니다.
  2. STD :: Distion에는 두 가지 구현이 있습니다. RandomAccessiterator를 만족시키는 유형의 경우 "Tail-Head"를 사용하고 Inputiterator를 만족시키는 유형의 경우 "iterator ++"에 의존하는 O (N) 알고리즘을 사용하여 주어진 곳에 도달 할 때까지 계산합니다. 꼬리.
  3. STD :: List는 RandomAccessiterator를 자랑하지 않으므로 크기는 O (n)입니다.

"왜"에 관해서는, 나는 std :: 목록이 순차적 인 액세스가 필요한 문제에 적합하다고 말할 수 있습니다. 크기를 클래스 변수로 저장하면 모든 인서트, 삭제 등에 오버 헤드가 소개 될 것이며, 그 폐기물은 STL의 의도에 따라 크지 않습니다. 일정한 시간 크기가 필요한 경우 ()은 std :: deque를 사용하십시오.

나는 개인적으로 스플 라이스가 O (n) 인 문제가 크기가 O (n)으로 허용되는 유일한 이유를 보지 못합니다. 당신은 당신이 사용하지 않는 것에 대한 비용을 지불하지 않습니다 중요한 C ++ 모토입니다. 이 경우 목록 크기를 유지하려면 목록 크기를 확인하든 아니든 모든 삽입/지우기에 추가 증분/감소가 필요합니다. 이것은 작은 고정 오버 헤드이지만 여전히 고려해야합니다.

목록의 크기를 확인하는 것은 거의 필요하지 않습니다. 총 크기를 돌보지 않고 처음부터 끝까지 반복하는 것이 무한히 더 일반적입니다.

나는 갈 것이다 원천 (보관소). SGI의 STL 페이지는 선형 복잡성을 가질 수 있다고 말합니다. 그들이 따르는 설계 지침은 목록 구현을 가능한 한 일반화하고 목록을 사용하는 데 더 많은 유연성을 허용하는 것이라고 생각합니다.

이 버그 보고서: [C++0x]std::list::크기에 복잡성, 캡처에 극심한 세부 사실의 구현에서는 GCC4.x 선형 시간과 어떻게 전환하여 일정한 시간을 위한 C++11 에서 오는(에서 사용 가능 5.0)인 ABI 호환성 문제입니다.

는 ncursesw 에는 와이드에 대한 GCC4.9 시리즈는 다음이 포함됩 면책 조항:

지원을 위한 C++11 은 아직도 실험,변경될 수 있습니다에서 호환 되지 않는 방법으로 보내 주시기 바랍니다.


동 버그 보고서가 여기에 참조: 해야 하는 std::list::크기가 일정한 복잡성에서는 C++11?

목록을 올바르게 사용하는 경우 차이가 주목되지 않을 수 있습니다.

목록은 복사하지 않고 재 배열하려는 빅 데이터 구조와 함께, 삽입 후 유효한 포인터를 유지하려는 데이터에 대해서는 양호합니다.

첫 번째 경우에는 차이가 없습니다. 두 번째에는 이전 (작은) 크기 () 구현을 선호합니다.

어쨌든 STD는 원시 속도보다 정확성과 표준 행동 및 '사용자 친화성'에 관한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top