Tôi thấy rằng set_intersection()
et al. từ tiêu đề algorithm
sẽ không hoạt động khi chúng yêu cầu rõ ràng đầu vào của chúng được sắp xếp - hãy đoán bạn đã loại trừ chúng. Nó xảy ra với tôi rằng cách tiếp cận "ngây thơ" của iterating thông qua băm A và tìm kiếm mọi phần tử trong hash B thực sự cung cấp cho bạn hiệu suất gần tối ưu, vì tra cứu liên tiếp trong băm B sẽ đi đến cùng một thùng băm (giả sử rằng cả hai băm đều sử dụng cùng hàm băm). Điều đó sẽ cung cấp cho bạn địa phương bộ nhớ phong nha, mặc dù các thùng này gần như chắc chắn được thực hiện dưới dạng danh sách được liên kết.
Dưới đây là một số mã cho unordered_set_difference()
, bạn có thể tinh chỉnh nó để làm cho các phiên bản cho bộ công đoàn và thiết lập sự khác biệt:
template <typename InIt1, typename InIt2, typename OutIt>
OutIt unordered_set_intersection(InIt1 b1, InIt1 e1, InIt2 b2, InIt2 e2, OutIt out) {
while (!(b1 == e1)) {
if (!(std::find(b2, e2, *b1) == e2)) {
*out = *b1;
++out;
}
++b1;
}
return out;
}
Giả sử bạn có hai unordered_set
s, x
và y
, bạn có thể đặt giao của họ trong z
sử dụng:
unordered_set_intersection(
x.begin(), x.end(),
y.begin(), y.end(),
inserter(z, z.begin())
);
Không giống như bdonlan's answer, này sẽ thực sự làm việc cho bất kỳ loại chìa khóa, và bất kỳ sự kết hợp của c ontainer loại (mặc dù sử dụng set_intersection()
dĩ nhiên sẽ nhanh hơn nếu các vùng chứa nguồn được sắp xếp). LƯU Ý: Nếu việc chiếm đóng thùng cao, có thể nhanh hơn để sao chép từng băm vào một số vector
, sắp xếp chúng và set_intersection()
chúng ở đó, vì việc tìm kiếm trong một nhóm chứa n phần tử là O (n).
Nguồn
2009-05-22 05:08:10
+1 Câu trả lời xuất sắc. Sẽ rất thú vị khi đánh giá mã này.Nó có thể thực sự nhanh hơn (nếu các bộ lớn hơn nhưng không quá lớn) để sao chép chúng vào một bộ được sắp xếp và chạy std :: set_intersection(). – paxos1977
Cảm ơn ceretullis. Có, tôi nghi ngờ rằng sẽ nhanh hơn nếu các thùng có dung lượng lớn, mặc dù trong trường hợp đó tôi nghi ngờ sao chép chúng vào vectơ và phân loại chúng sẽ nhanh hơn, chỉ vì có ít chi phí bộ nhớ hơn và không có con trỏ theo đuổi. (Sắp xếp một vector và tạo một tập hợp được sắp xếp đều là O (nlog n).) –
Tôi hơi lo lắng. Chúng ta có chắc rằng std :: find sẽ hoạt động tốt với các trình vòng lặp thành 'set'? Sẽ không tìm thấy chỉ đơn giản là lặp qua tất cả các yếu tố trong tập thứ hai, trong khi chúng tôi muốn nó sử dụng băm để loopup? Không nên hàm chỉ cần tham chiếu đến đối tượng đã đặt và sau đó sử dụng phương thức '.count'? –