Vấn đề là c
của bạn trống vì đã được khởi tạo mà không có phần tử nào, chưa kể đến cuộc gọi không cần thiết đến clear()
. std::merge()
mất một đối số đầu ra đầu ra làm đối số cuối cùng của nó. Nếu c.begin()
đề cập đến sự bắt đầu của số std::vector
rằng đã chứa đủ yếu tố, thì đây không phải là vấn đề — những yếu tố đó sẽ chỉ bị ghi đè. Vì vậy, bạn đang gọi hành vi không xác định bằng cách viết các giá trị vào bộ nhớ qua phần cuối của vectơ.
Để đảm bảo rằng c
có đủ không gian cho các yếu tố, bạn có thể làm điều này:
c.resize(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
Tuy nhiên, nó là thành ngữ hơn để sử dụng một std::back_insert_iterator
, một iterator đầu ra mà các cuộc gọi push_back()
. Để có hiệu quả tốt hơn, bạn có thể gọi reserve()
trên véc tơ trước. Điều này đảm bảo rằng c
chỉ cần phân bổ bộ nhớ một lần, thay vì khi nó phát triển trong khi gọi đến std::merge()
. Giải pháp cuối cùng trông như thế này:
#include <iterator>
// ...
c.reserve(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
Nguồn
2012-02-02 16:00:56
Câu trả lời của bạn là đúng, nhưng tôi sẽ không sử dụng cụm từ 'dự trữ', vì nó có nghĩa là một điều hoàn toàn khác với 'thay đổi kích thước'. –
Tại sao bạn chọn gọi giải pháp thứ hai “tốt hơn”? Tôi muốn nói ngược lại vì kích thước được biết và biến thể đầu tiên chắc chắn hiệu quả hơn và không thực sự phức tạp hơn thứ hai. –
@KonradRudolph: cái thứ hai ít bị lỗi hơn, và nói chung hơn, bạn có thể biết kích thước trong trường hợp này, nhưng đôi khi bạn thì không. – Fanael