2013-03-04 32 views
5

Tôi đang cố gắng tìm hiểu C++ với một nền Java nhỏ và tôi đang cố viết mã trả về giao điểm của hai danh sách. Tôi tin rằng tôi có ý tưởng đúng về mặt khái niệm, nhưng tôi đang gặp rắc rối với cú pháp vì không có gì biên dịch.Người mới bắt đầu C++: Biến đổi chỉ mục-cú pháp thành cú pháp vòng lặp

Dưới đây là đoạn code tôi đã đưa ra:

#include <iostream> 
using namespace std; 
#include <list> 

template <typename Object> 
list<Object> intersection(const list<Object> & L1, const list<Object> & L2){ 

    std::list<Object> result;     
    int pos1 = 0; 
    int pos2 = 0; 

    while (pos1 < L1.size() && pos2 < L2.size()) { 
    if (L1[pos1] > L1[pos2]) { 
     pos1++; 
    } else if (L2[pos2] > L1[pos1]) { 
     pos2++; 
    } else { 
     result.push_back(L2[pos2]); 
     pos1++; 
     pos2++; 
    } 
    } 
    return result; 

} 

Những điều tôi nghĩ rằng tôi cần: một iterator (tôi chắc chắn rằng con đường tôi đang truy cập vào danh sách là không đúng)

+1

Tôi đã sửa đổi tiêu đề để làm cho nó (hy vọng) mô tả hơn và cho biết đây là vấn đề tương đối chung, thú vị cho người dùng trong tương lai. Tôi hy vọng điều này là ok (xin vui lòng trở lại nếu không). – jogojapan

+1

Vì bạn là người mới bắt đầu tại C++, có thể đáng nói rằng bạn không nên sử dụng 'std :: list' ... mãi mãi. (Không phải vì có gì sai với lớp C++, nhưng vì nó là một cấu trúc dữ liệu khủng khiếp). Khi bạn chỉ cần một vùng chứa, mặc định là 'vector ' thay thế. (Điều đó cũng sẽ cho phép mã của bạn hoạt động với các chỉ mục thay vì các trình lặp) – jalf

+0

Điểm tốt. 'vector' tốt hơn trong hầu hết các trường hợp, nhưng tôi nghĩ là tốt để biết các ưu điểm và nhược điểm của cả' list' và 'vectơ' và nếu bạn muốn viết mã C++ tốt tại một số điểm bạn cần biết về con trỏ/vòng lặp. – Ari

Trả lời

4

Thay đổi pos1 và pos2 để lặp:

list<Object> intersection(const list<Object> & L1, const list<Object> & L2){ 
    std::list<Object> result;     
    std::list<Object>::iterator pos1 = L1.begin(), pos2 = L2.begin(); 
    while (pos1 != L1.end() && pos2 != L2.end()) { 
    if (*pos1 > *pos2) { //works only if pos1 != L1.end() and pos2 != L2.end() 
     pos1++; 
     ... 

pos1 = L1.begin() điểm pos1 đến phần tử đầu tiên của L1.

++pos1 di chuyển iterator về phía trước, để phần tử tiếp theo

*pos1 được phần tử từ pos1

pos1 != L1.end() kiểm tra nếu pos1 đạt cuối danh sách. Bạn không thể lấy phần tử từ pos1 khi pos1 == L1.end().

+0

Cảm ơn bạn rất nhiều, đây chính xác là những gì tôi cần. –

+1

Trình lặp cần phải là 'const'. –

2

Bạn cần const_iterator không phải là iterator.

Tất cả các lớp chứa C++ have typedefs on them xác định những thứ như loại chúng chứa và loại trình lặp, trong số những thứ khác.

Trong trường hợp của bạn list<Object>::value_type thuộc loại Object. Vì vậy, bạn có thể nói:

list<Object>::value_type object = Object(); 

Tương tự list<Object>::iterator là loại trình lặp được sử dụng để đi qua vùng chứa. Bạn có thể lấy các trình vòng lặp biểu diễn phần đầu và cuối của vùng chứa bằng cách sử dụng begin()end().

Nếu vùng chứa của bạn là const như trong câu hỏi của bạn, begin và kết thúc không trả về iterator, chúng sẽ trả lại const_iterator. Bạn không thể gán điều này cho loại iterator. Chúng khác nhau như một cho phép bạn sửa đổi giá trị, cái kia thì không.

Bạn có thể khắc phục sự cố của mình bằng cách sử dụng const_iterator. Tuy nhiên, có một số cách khác để sửa lỗi này.

  • auto có nghĩa là bạn không phải rõ ràng về loại đó. Nó phù hợp với bạn.
  • Mẫu có thể sử dụng các thông số chung, do đó, một lần nữa, bạn không phải rõ ràng.
  • Thư viện chuẩn có các thuật toán khác nhau có thể đã thực hiện những gì bạn muốn (ví dụ: set_intersection).
Các vấn đề liên quan