2011-12-13 33 views
20

Làm cách nào để xóa thành viên cuối cùng khỏi tập hợp?Xóa thành viên cuối cùng của std :: set

Ví dụ:

set<int> setInt; 
setInt.insert(1); 
setInt.insert(4); 
setInt.insert(3); 
setInt.insert(2); 

Làm thế nào tôi có thể xóa 4 từ setInt? Tôi đã thử một cái gì đó như:

setInt.erase(setInt.rbegin()); 

nhưng tôi đã nhận được lỗi.

+0

Doh bạn đúng Tôi quên thiết lập không có truy cập ngẫu nhiên iterator. Sử dụng 'setInt.erase (std :: prev (setInt.end()));' – AJG85

Trả lời

17
if (!setInt.empty()) { 
    std::set<int>::iterator it = setInt.end(); 
    --it; 
    setInt.erase(it); 
} 

Bằng cách này, nếu bạn đang làm này rất nhiều (thêm điều cần một tập theo thứ tự tùy ý và sau đó loại bỏ các yếu tố đầu), bạn cũng có thể có một cái nhìn tại std::priority_queue, xem liệu phù hợp với bạn sử dụng.

+0

Ồ, thật tiếc, tôi nghĩ rằng 'if' là một vòng lặp' for' vì lý do nào đó ... –

30

trong C++ 11

setInt.erase(std::prev(setInt.end())); 

Bạn có thể quyết định cách bạn muốn để xử lý trường hợp tập trống.

1

Nếu bạn muốn xóa 4 thay vì cuối cùng, bạn nên sử dụng phương pháp tìm. Tùy thuộc vào trường hợp sử dụng 4 có thể không phải là trường hợp cuối cùng.

std::set<int>::iterator it = setInt.find(4); 
if(it != setInt.end()) { 
    setInt.erase(it); 
} 

Nếu bạn muốn xóa việc sử dụng yếu tố cuối cùng:.

if (!setInt.empty()) { 
    setInt.erase(--setInt.rbegin().base()); 
    // line above is equal to 
    // setInt.erase(--setInt.end()); 
} 

Trong khi tôi không chắc chắn nếu - * end(); là O.K. Tôi đã đọc một số. Vì vậy, - trên rbegin(). Base() dẫn đến kết quả tương tự như - on end(). Và cả hai sẽ hoạt động.

+0

setInt. [Rend() ] (http://www.cplusplus.com/reference/stl/set/rend/) trả về một iterator trỏ trước setInt.begin(), vì vậy nó không có gì để làm với phần cuối của tập. – wigy

+0

bạn đúng là rbegin tôi định viết. :-(Tôi sửa lỗi này – Totonga

+1

Đề xuất của bạn khác với đề xuất nào trong câu hỏi, như chúng tôi đã biết không hoạt động? – bitmask

0

Kiểm tra xem tập hợp có trống hay không. Nếu không, sau đó lấy phần tử cuối cùng và thiết lập làm trình vòng lặp và làm giảm trình lặp đó và xóa phần tử cuối cùng.

if (!setInt.empty()) 
{ 
    std::set<int>::iterator it = setInt.end(); 
    --it; 
    if(it != setInt.end()) { 
    setInt.erase(it); 
    } 
} 
5

tôi muốn đề nghị sử dụng một tên khác cho rbegin trong đó có một loại thích hợp:

setInt.erase(--setInt.end()); 

Giả sử bạn kiểm tra rằng setInt là không có sản phẩm nào!

Btw. điều này hoạt động bởi vì bạn có thể gọi toán tử giảm tốc đột biến trên một tạm thời (loại std::set<int>::iterator). Tạm thời này sẽ được chuyển tới hàm xóa.

+0

Xảo quyệt, vì không giống như 'std :: vector :: iterator', không có cách nào mà' std :: set :: iterator' có thể là một con trỏ. Nó phải là một loại lớp, do đó, tạm thời phải được giảm dần. –

+0

@SteveJessop: Họ là :) – bitmask

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