2012-05-07 72 views
11

Tôi bị kẹt khi cố gắng tìm cách chèn một vectơ cho một giá trị trong bản đồ. Ví dụ:Chèn vectơ cho giá trị trong bản đồ trong C++

#include <iostream> 
#include <vector> 
#include <map> 

using namespace std; 

int main() 

{ 

    map <int, vector<int> > mymap; 

    mymap.insert(pair<int, vector<int> > (10, #put something here#)); 

    return 0; 
} 

Tôi không biết cú pháp nào nên sử dụng chèn vectơ cho giá trị. Tôi đã thử {1,2}, nhưng điều đó không thành công. Tôi nên sử dụng cú pháp nào?

Mọi thứ đều hoạt động nếu tôi tuyên bố trước một vector và đặt tên cho nó, nhưng tôi không muốn làm điều đó, vì tôi muốn có bản đồ có nhiều vectơ.

Cảm ơn bạn trước

+0

Làm cách nào để bạn biết nội dung nên là gì? – mkb

Trả lời

7

Về cơ bản câu hỏi của bạn không phải là chèn std::vector vào một std::map. Câu hỏi của bạn là làm cách nào để bạn có thể dễ dàng tạo ẩn danhstd::vector với các giá trị phần tử ban đầu tùy ý.

Trong ISO C++ 03, bạn không thể. Tuy nhiên, C++11 allows using initialization lists for this.

Nếu bạn đang mắc kẹt với một trình biên dịch C++ 03, bạn có thể có thể tạo một hàm helper để trả về một vector với các yếu tố quy định:

std::vector<int> make_vector(int a, int b) 
{ 
    std::vector<int> v; 
    v.push_back(a); 
    v.push_back(b); 
    return v; 
} 

Nếu các vectơ bạn đang chèn có kích thước khác nhau, bạn có thể sử dụng một hàm variadic, mặc dù làm như vậy sẽ yêu cầu bạn phải truyền theo số lượng các phần tử hoặc có một giá trị sentinel dành riêng.

+0

Bạn có thể tạo một vector ẩn danh, không chỉ với các giá trị. Chỉ cần lấy nó bằng cách tham khảo sau khi bạn thực hiện nó và thêm chúng vào sau khi xây dựng. Hàm trợ giúp thực sự là cách tốt nhất mặc dù trong C++ 03. –

2

#put something here# = vector<int>{1,2}

Tôi ngạc nhiên rằng mặc dù {1,2} đã không làm việc. Bạn không sử dụng trình biên dịch C++ 11? Nếu không thì bạn chỉ có thể tạo vectơ với hàm tạo mặc định ở đó (không có giá trị), hoặc điền nó với các giá trị đầu tiên và dán nó vào.

+0

'vector' cũng có một hàm tạo sẽ tạo một vectơ mới với n bản sao có cùng giá trị ban đầu. – mkb

+0

trình biên dịch của tôi là Mã :: Khối 10.05 và các đề xuất của bạn không hoạt động đối với tôi. Tôi đoán rằng nó không thể được thực hiện với trình biên dịch của tôi. – Akavall

+0

@Akavall, đó là IDE của bạn. Nó sử dụng một số phiên bản cũ của GCC với liên kết tải xuống, vì vậy bạn phải tự nâng cấp trình biên dịch và thư viện. – chris

12

Nếu bạn muốn một vector trống bạn có thể làm:

mymap.insert(pair<int,vector<int> >(10, vector<int>())); 

Sau đó bạn có thể thêm bất cứ điều gì yếu tố mà bạn muốn với một cái gì đó như:

mymap[10].push_back(1); 
mymap[10].push_back(2); 

Sửa: khẳng định không chính xác Removed rằng các vectơ sẽ được sao chép nếu/khi bản đồ phát triển. Như các bình luận đã chỉ ra, điều này không đúng đối với std :: map, dựa trên node.

+0

'bản đồ' lưu trữ theo giá trị có, nhưng việc phát triển bản đồ sẽ _never ever_ sao chép cặp khóa/giá trị. Giai đoạn. Không bao giờ. Vì vậy, chỉ cần đặt các vector trong đó. Tương tự với 'list',' set', 'multimap' và' multiset'. Chúng được gọi là "vùng chứa dựa trên nút" vì thuộc tính này. –

+0

Câu trả lời của bạn là sai bắt đầu từ 'Nhưng', đó là khá nhiều. Việc phát triển một 'bản đồ' không ** không ngụ ý di chuyển nội dung của nó. Không bao giờ. Một trong những yêu cầu không may (1) của 'map' là khi thiết lập một phần tử sẽ không di chuyển cho đến khi nó bị xóa. (1) Không may bởi vì nó có nguồn gốc từ việc thực hiện đã biết hơn là suy nghĩ từ nguyên tắc đầu tiên (về vai trò của container) và ngăn cản việc triển khai hiệu quả hơn cây đỏ đen, chẳng hạn như cây B. –

5

Nếu bạn đang sử dụng C++ 11 bạn có thể sử dụng vector của danh sách khởi constructor (các nhà xây dựng cuối cùng trong danh sách đó) mà sẽ trông như thế này:

mymap.insert(pair<int, vector<int> > (10, {1, 2, 3})); 

Nếu bạn chỉ có thể sử dụng C++ 03, vector có một hàm tạo có kích thước và giá trị mặc định cho mỗi phần tử có thể đủ cho bạn. Nếu không, bạn sẽ phải xây dựng vectơ và sau đó chèn nó vào. Nếu bạn muốn tránh một bản sao unnessicary của vector khi chèn bạn có thể swap nó trong như vậy:

vector<int> myvec; 
myvec.push_back(1); 
myvec.push_back(2); 
mymap[10].swap(myvec); 

Bằng cách này, vector sẽ không cần phải được sao chép. Bạn sẽ nhận được một xây dựng mặc định thêm vector nhưng đó không phải là rất tốn kém.

1

Điều này sẽ hoạt động trong trình biên dịch C++ 2003.

#include <iostream> 
#include <vector> 
#include <map> 
#include <cassert> 

using namespace std; 

std::vector<int> make_vector(int a, int b) { 
    std::vector<int> result; 
    result.push_back(a); 
    result.push_back(b); 
    return result; 
} 

int main() 

{ 

    map <int, vector<int> > mymap; 

    mymap.insert(make_pair(10, make_vector(1,2))); 
    // Or, alternatively: 
    // mymap[10] = make_vector(1,2); 

    assert(mymap[10][0] == 1); 
    assert(mymap[10][1] == 2); 

    return 0; 
} 
1

C++ 03 không có danh sách khởi tạo, có thể gây đau khi khởi tạo bộ sưu tập.

Nếu bạn không thể nâng cấp lên phiên bản trình biên dịch hiện đại hơn, bạn luôn có thể sử dụng thư viện Boost.Assignment. Nó có chức năng list_of chính xác cho việc này.

#put something here# -> boost::assign::list_of(1)(2) 
Các vấn đề liên quan