Tôi phải thừa nhận tôi khá thích giải pháp Potatoswatter ... khá.
Như ông đã chứng minh, đây không phải là vấn đề về thuật toán, mà là sự lặp lại. Tuy nhiên giải pháp của ông không hoàn toàn phù hợp với hóa đơn bởi vì thử nghiệm cho các end
của iteration là rất khó khăn: nó đòi hỏi nhiều chăm sóc trong việc chuẩn bị các container và tạo ra các iterators để tránh undefined hành vi.
Tôi nghĩ rằng vấn đề có thể được thể hiện tốt hơn nhiều bằng cách sử dụng một khái niệm khá giống với các trình vòng lặp: các khung nhìn.
Chế độ xem là giao diện Bộ điều hợp trên một hoặc nhiều vùng chứa. Nó không thực sự chứa bất cứ điều gì chính nó (đó là phần quan trọng). Tuy nhiên, nó cho thấy một giao diện tương tự như giao diện của một vùng chứa để bạn có thể mã hóa với các thành ngữ thông thường.
Những điều đẹp về lượt xem, là bạn thường có thể soạn chúng.
Ví dụ, một cái nhìn rất đơn giản:
/// Only allow to see a range of the container:
/// std::vector<int> v(40, 3); // { 3, 3, 3, ... }
/// auto rv = make_range_view(v, 4, 5);
/// rv exposes the elements in the range [4,9)
/// in debug mode, asserts that the range is sufficiently large
template <typename Container>
class range_view
{
};
Đối với câu hỏi của bạn, bạn thà tạo ra một interleave_view
:
/// Allow to interleave elements of 2 containers each at its own pace
/// std::vector<int> v(40, 3);
/// std::set<int> s = /**/;
///
/// auto iv = make_interleave_view(v, 3, s, 1);
/// Takes 3 elements from v, then 1 from s, then 3 from v, etc...
template <typename C1, typename C2>
class interleave_view
{
};
Ở đây, vấn đề của iterator cuối cùng là bằng cách nào đó giảm bớt bởi vì chúng tôi biết cả hai thùng chứa và do đó chúng tôi có thể tự tạo ra các trình vòng lặp, đảm bảo chúng tôi chuyển các thông số thích hợp.
Tất nhiên nó có thể trở nên tẻ nhạt hơn một chút nếu các thùng chứa không cung cấp thành viên "kích thước" hiệu quả (list
không, đó là O (n)). Tuy nhiên, nguyên tắc chung cho phép bạn kiểm soát nhiều hơn (và cho phép nhiều kiểm tra hơn), và an toàn hơn để sử dụng bởi vì bạn kiểm soát chính xác việc tạo các trình vòng lặp.
Lưu ý rằng trong C++ 0x, interleave_view
thường chứa một số chuỗi không bị chặn.
Điều gì xảy ra khi kết thúc c? Bạn có muốn có nó 4 4 8 .... 8 8 8 8 hoặc chỉ dừng lại sáp nhập aIt là a.end() như trong ví dụ của bạn? – dyp
Vì vậy, điều gì sẽ xảy ra nếu một trong hai vector đầu vào không có đủ yếu tố? – AnT
STL đã có một quy ước cho điều đó - những gì hiện 'std :: transform' làm gì khi chuỗi đầu vào không có đủ yếu tố? – MSalters