2009-12-03 108 views
22

Tôi có mã python có chứa mã sau đây.Dịch từ điển python sang C++

d = {} 

d[(0,0)] = 0 
d[(1,2)] = 1 
d[(2,1)] = 2 
d[(2,3)] = 3 
d[(3,2)] = 4 

for (i,j) in d: 
    print d[(i,j)], d[(j,i)] 

Thật không may lặp lại tất cả các khóa trong python không thực sự đủ nhanh cho mục đích của tôi và tôi muốn dịch mã này sang C++. Cấu trúc dữ liệu C++ tốt nhất để sử dụng cho một từ điển python có các bộ dữ liệu là các khóa của nó là gì? Điều gì sẽ là tương đương với C++ của đoạn mã trên?

Tôi đã xem các ma trận thưa thớt trong thư viện tăng nhưng không thể tìm thấy cách dễ dàng để chỉ lặp lại các phần tử khác 0.

+0

Bạn đã cân nhắc bố cục dữ liệu khác chưa. Nếu (i, j) luôn được ghép nối với (j, i) thì bạn có thể không thực sự cần cả hai. Bạn chỉ có thể xây dựng hiệp hội tại thời điểm bạn đang xây dựng từ điển. Bạn chỉ có thể lưu trữ một dict của (i, j) trong cửa hàng nhập cảnh (d (i, j), d (j, i)). Điều này giả định những con số trong tuple có thể được tùy ý ra lệnh, điều đó có lẽ đúng. –

+0

Ngoài ra, nếu bạn chỉ đang đi bộ, lưu trữ chúng trong một danh sách và đi bộ danh sách. –

Trả lời

37

Một từ điển sẽ là một std :: bản đồ trong C++, và một tuple với hai yếu tố sẽ là một std :: pair.

mã python cung cấp sẽ dịch để:

#include <iostream> 
#include <map> 

typedef std::map<std::pair<int, int>, int> Dict; 
typedef Dict::const_iterator It; 

int main() 
{ 
    Dict d; 

    d[std::make_pair(0, 0)] = 0; 
    d[std::make_pair(1, 2)] = 1; 
    d[std::make_pair(2, 1)] = 2; 
    d[std::make_pair(2, 3)] = 3; 
    d[std::make_pair(3, 2)] = 4; 

    for (It it(d.begin()); it != d.end(); ++it) 
    { 
     int i(it->first.first); 
     int j(it->first.second); 
     std::cout <<it->second <<' ' 
       <<d[std::make_pair(j, i)] <<'\n'; 
    } 
} 
+2

Điều đó thực sự rất hay. Làm tốt lắm. Rất giảng dạy cho một người như tôi làm việc để nâng cấp kỹ năng của họ từ trường C++ cũ lên C++ hiện đại. –

+1

'd [* it]' phải là 'it-> second' –

+0

' d [* it] 'đưa ra lỗi trên vs.net 2005. Hãy thử' it-> second' – chollida

8

Loại là

std::map< std::pair<int,int>, int> 

Mã này để thêm các mục để lập bản đồ cũng giống như ở đây:

typedef std::map< std::pair<int,int>, int> container; 

container m; 

m[ make_pair(1,2) ] = 3; //... 

for(container::iterator i = m.begin(); i != m.end(); ++i){ 
    std::cout << i.second << ' '; 
    // not really sure how to translate [i,j] [j,i] idiom here easily 
} 
+1

Bạn không thể sử dụng 'typename' khi loại không phải là tên phụ thuộc. –

+0

@Roger: bạn nói đúng, cố định rằng "typename container :: iterator" – catwalk

4

Có một cái nhìn tại Boost.python. Nó dành cho sự tương tác giữa python và C++ (về cơ bản xây dựng các thư viện python bằng cách sử dụng C++, nhưng cũng để nhúng python vào các chương trình C++). Hầu hết các cấu trúc dữ liệu pythons và các tương đương C++ của chúng được mô tả (không được kiểm tra cho cái bạn muốn).

3

std::map hoặc nhiều khả năng std::tr1::unordered_map/boost::unordered_map (aka hash_map) là những gì bạn muốn.

Ngoài ra, như kriss đã nói, Boost.Python là một ý tưởng hay để xem tại đây. Nó cung cấp một phiên bản C++ của lớp dict của python, vì vậy nếu bạn đang thực hiện các công cụ đa ngôn ngữ, nó có thể hữu ích.

0

Là câu trả lời trực tiếp cho câu hỏi của bạn (đối với phần python nhìn vào câu trả lời khác của tôi). Bạn có thể quên phần tuple nếu muốn. Bạn có thể sử dụng bất kỳ khóa/giá trị kiểu ánh xạ nào (băm, v.v.) trong C++, bạn chỉ cần tìm một hàm khóa duy nhất. Trong một số trường hợp có thể dễ dàng. Ví dụ nếu bạn hai số nguyên là số nguyên từ 1 đến 65536 bạn chỉ có thể sử dụng số nguyên 32 bit với mỗi phần 16 bit một trong các phím. Một sự thay đổi đơn giản và một 'hoặc' hoặc + để kết hợp hai giá trị sẽ làm các trick và nó rất hiệu quả.

1

Bạn có muốn gọi thường trình C++ tối ưu qua Python không? Nếu có, hãy đọc tiếp:

Thông thường, tôi sử dụng PyYaml khi xử lý các từ điển bằng Python. Có lẽ bạn có thể liên kết trong một cái gì đó giống như LibYAML hoặc yamlcpp tới:

  1. Dịch một cuốn từ điển Python vào một chuỗi YAML
  2. Sử dụng Python để gọi một hàm C++ bao bọc bằng một cái gì đó giống như SWIG, lấy chuỗi YAML như một tham số.
  3. Dùng C++ thư viện để phân tích YAML & có được một đối tượng std::map
  4. Vận hành trên đối tượng std :: map

Cảnh báo: Tôi chưa bao giờ cố gắng này, nhưng sử dụng công cụ tìm kiếm ưa thích của mọi người trên "yaml std::map" mang lại rất nhiều các liên kết thú vị

1

Bản đồ thường được triển khai dưới dạng cây nhị phân cân bằng chứ không phải bảng băm. Đây không phải là trường hợp cho một dict Python. Vì vậy, bạn cần cấu trúc dữ liệu tương đương C++ O (1) để sử dụng các cặp của bạn.

Các vấn đề liên quan