2010-08-19 32 views

Trả lời

37

loại bỏ [...] đặt các yếu tố 'loại bỏ' ở phần đầu của chuỗi

Cái gì? Không. Cả hai remove_ifpartition đặt các phần tử "tốt" trước. partition đặt các phần tử "xấu" sau đó, trong khi remove_if không chỉ định nội dung xuất hiện sau đó - đó có thể là các phần tử xấu, nhưng nó cũng có thể là bản sao của bất kỳ phần tử nào (hoặc tốt hoặc xấu).

Ví dụ, nếu bạn partition 1 2 3 4 5 trên thậm chí, bạn có thể nhận được 2 4 5 3 1 (lưu ý rằng mỗi phần tử xảy ra đúng một lần), trong khi đó nếu bạn remove_if các yếu tố kỳ quặc, có lẽ bạn nhận được 2 4 3 4 5 (lưu ý các bản sao).

+0

cảm ơn, tôi hiểu rằng –

2

Từ C++ Thư viện Tiêu chuẩn: A Hướng dẫn và tham khảo

remove() - Loại bỏ các yếu tố với một giá trị nhất định, hợp lý chỉ bằng cách ghi đè lên chúng với các yếu tố sau đây mà không được loại bỏ. Không thay đổi số lượng các phần tử trong phạm vi hoạt động của chúng. Thay vào đó, họ trở về vị trí của các mới "kết thúc" của dãy núi này

phân vùng() - Thay đổi thứ tự của các yếu tố để các phần tử phù hợp với một tiêu chí là ở phía trước

stable_partition() - Tương tự như phân vùng() nhưng giữ gìn trật tự tương đối của khớp và các yếu tố nonmatching

+0

giải thích hay. – Chubsdad

-1

phân vùng - "nhóm" các yếu tố của một container theo một vị nào đó (ví dụ như số lẻ và chẵn số trong một std :: vector)

xóa - xóa chứng chỉ giá trị ain từ thùng chứa; thực sự yếu tố này được chuyển đến cuối container ban đầu, một iterator đến hết mới được trả về và các yếu tố "gỡ bỏ" vẫn truy cập

EDIT:

remove - loại bỏ một giá trị nhất định từ một container; các phần tử KHÔNG được chuyển đến cuối container ban đầu như đã nói ở trên, một trình lặp tới đầu mới được trả về nhưng các trình vòng lặp trong phạm vi [newEnd, last) vẫn còn có thể truy cập được do đó các phần tử mà chúng trỏ tới không xác định.

+0

Thats sai, loại bỏ ghi đè các yếu tố 'loại bỏ' bởi những yếu tố sau, do đó, không phải tất cả chúng có thể truy cập được sau đó ... – MartinStettner

+0

Muốn biết câu trả lời của tôi là gì nếu có thể. Có lẽ tôi sẽ học một cái gì đó trong quá trình này. – celavek

+0

@MartinStettner Tôi nghĩ bạn đã sai. Từ tài liệu "Loại bỏ các loại bỏ khỏi phạm vi [đầu tiên, cuối cùng) tất cả các phần tử bằng giá trị. Đó là, loại bỏ trả về một iterator new_last sao cho phạm vi [first, new_last) không chứa các phần tử bằng giá trị. [1] trong phạm vi [new_last, last] là tất cả vẫn không thể chấp nhận được, nhưng các phần tử mà chúng trỏ đến không xác định. Xóa là ổn định, có nghĩa là thứ tự tương đối của các phần tử không bằng với giá trị không thay đổi. " http://www.sgi.com/tech/stl/remove.html – celavek

12

remove_if không đặt các phần tử đã xóa ở bất kỳ đâu; các phần tử sau khi kết thúc mới sẽ có giá trị cũ của chúng, vì vậy một số phần tử đã loại bỏ có thể bị thiếu và một số phần tử được bảo tồn có thể bị trùng lặp. Đây là nhanh hơn partition và có thể được thực hiện với các trình lặp vòng chuyển tiếp trong khi partition yêu cầu trình vòng lặp hai chiều.

Cập nhật: trong C++ 0x, partition sẽ chỉ yêu cầu chuyển tiếp vòng lặp, nhưng sẽ chậm hơn nếu các trình vòng lặp không hai chiều.

+0

Nếu 'phân vùng' yêu cầu trình vòng lặp hai chiều, thì nó hoạt động như thế nào trên' forward_list'? – fredoverflow

+0

@FredOverflow: vì C++ 0x thay đổi hợp đồng 'phân vùng' để chuyển tiếp trình lặp. –

+1

'phân vùng' nhanh hơn' remove_if' trong một số trường hợp. Nếu phần tử cần xóa là lúc bắt đầu của một vectơ lớn, 'remove_if' sẽ di chuyển toàn bộ điều sang bên trái trong khi' phân vùng' sẽ hoán đổi phần tử cần xóa với phần tử cuối cùng. – aberaud

4

Nếu tôi hiểu đúng, remove không thực sự hoán đổi bất kỳ phần tử nào mà chỉ di chuyển các phần tử mà vị từ (trong trường hợp remove_if) là sai cho phần đầu của chuỗi. Nếu bạn có

a = [1,1,1,2,3]

và gọi remove(a.begin(),a.end(),1), bạn sẽ phải

a = [2,3,1,2,3]

sau đó. remove trả về một trình lặp cho phần tử thứ ba trong trường hợp này (nếu tôi nhớ chính xác ...)

partition mặt khác giữ lại tất cả các phần tử gốc của chuỗi nhưng thay đổi thứ tự của chúng sao cho các phần tử mà vị từ đã cho là đúng được đặt trước các phần tử không phải là nó.

partition(a.begin(), a.end(), not_equal<int>(1)) mang

a = [2,3,1,1,1]

+2

Lưu ý rằng nó không được bảo đảm những gì 'std :: remove()' 's lá phía sau _after_ mới iterator kết thúc nó trả về. Mặc dù kết quả bạn hiển thị có khả năng, nhưng nó không được đảm bảo. – sbi

+0

Tôi nghĩ 'std :: remove' được đảm bảo để lại các phần tử đằng sau vòng lặp kết thúc mới không thay đổi (chúng cũng sẽ vẫn có thể truy cập được). Nhưng tôi có thể đã được chứng minh sai theo tiêu chuẩn :) ... – MartinStettner

+0

Tiêu chuẩn không xác định những gì xảy ra với các phần tử sau khi kết thúc phạm vi mới. Mặc dù thật khó để tưởng tượng rằng bất kỳ việc triển khai hợp lý nào sẽ chạm vào chúng, không có sự đảm bảo nào. –

Các vấn đề liên quan