2009-12-03 39 views
22

Tengo el código de Python que contiene el siguiente código.Traduciendo el diccionario de Python a 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)] 

bucle desgracia sobre todas las teclas en Python no es lo suficientemente rápido para mi propósito, y me gustaría traducir el código en C++. ¿Cuál es la mejor estructura de datos de C++ para usar en un diccionario de Python que tiene tuplas como claves? ¿Cuál sería el equivalente en C++ del código anterior?

Miré las matrices dispersas en la biblioteca de impulso, pero no pude encontrar una manera fácil de recorrer solo los elementos distintos de cero.

+0

¿Ha considerado otro diseño de datos. Si (i, j) siempre está emparejado con (j, i), entonces puede que realmente no necesite ambos. Podrías construir la asociación en el momento en que estás construyendo el diccionario. Puede almacenar un dict de (i, j) en el almacén de entrada (d (i, j), d (j, i)). Esto supone que los números en la tupla podrían ordenarse arbitrariamente, lo que probablemente sea cierto. –

+0

Además, si solo está caminando por las tuplas, guárdelas en una lista y recorra la lista. –

Respuesta

37

Un diccionario sería un std :: mapa en C++ y una tupla con dos elementos sería un std :: pair

código proporcionado La pitón se traduciría en:

#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

Eso es muy bueno. Buen trabajo. Muy instructivo para alguien como yo que trabaja en mejorar sus habilidades desde la vieja escuela C++ hasta la moderna C++. –

+1

'd [* it]' debe ser 'it-> second' –

+0

' d [* it] 'da errores en vs.net 2005. Pruebe' it-> second' – chollida

8

El tipo es

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

El código para agregar entradas al mapa es como aquí:

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

No puede usar 'typename' cuando el tipo no es un nombre dependiente. –

+0

@Roger: tienes razón, corrigió ese "typename container :: iterator" – catwalk

4

Tenga una mirada en Boost.python. Es para la interacción entre Python y C++ (básicamente construyendo python libs usando C++, pero también para incrustar python en programas C++). Se describen la mayoría de las estructuras de datos de pitones y sus equivalentes de C++ (no se verificó para el que se desea).

3

std::map o más probablemente std::tr1::unordered_map/boost::unordered_map (también conocido como hash_map) es lo que desea.

Además, como dijo kriss, Boost.Python es una buena idea para ver aquí. Ya proporciona una versión en C++ de la clase dict de Python, por lo que si estás haciendo un intercambio de idiomas, puede ser útil.

0

Como respuesta directa a su pregunta (para la parte de python vea mi otra respuesta). Puedes olvidar la parte tuple si quieres. Puede usar cualquier tipo de clave/valor de mapeo (hash, etc.) en C++, solo tiene que encontrar una función clave única. En algunos casos, eso puede ser fácil. Por ejemplo, si los dos enteros son enteros entre 1 y 65536, podría usar un entero de 32 bits con cada parte de 16 bits, una de las claves. Un cambio simple y un 'o' o + para combinar los dos valores harían el truco y es muy eficiente.

1

¿Desea llamar a una rutina de C++ optimizada a través de Python? Si es así, siga leyendo:

Muchas veces uso PyYaml cuando trato con diccionarios en Python. Tal vez usted podría enlazar en algo así como LibYAML o yamlcpp a:

  1. traducir un diccionario de Python en una cadena YAML
  2. uso de Python para llamar a una función de C++ envuelto usando algo como SWIG, teniendo la cadena YAML como un parámetro.
  3. uso de un biblioteca de C++ para analizar la YAML & obtener un objeto std::map
  4. operar en std :: mapa de objetos

Advertencia: nunca he probado esto, pero utilizando el motor de búsqueda favorito de todos en "yaml std::map" produce mucha de enlaces interesantes

1

El mapa a menudo se implementa como un árbol binario equilibrado y no como una tabla hash. Este no es el caso para un dict de Python. Entonces necesita una estructura de datos equivalente a C++ O (1) para usar sus pares.

Cuestiones relacionadas