unitario rampa laplace impulso funcion escalon electricos ecuaciones dirac diferenciales circuitos c++ xml iterator boost-propertytree

c++ - laplace - funcion rampa y escalon



¿Cómo iterar un árbol de propiedades de impulso? (5)

Aquí es lo que se me ocurrió después de mucha experimentación. Quería compartirlo en la comunidad porque no podía encontrar lo que quería. Todo el mundo parecía simplemente publicar la respuesta de los documentos de impulso, que me pareció insuficiente. De todos modos:

#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> #include <string> #include <iostream> using namespace std; using boost::property_tree::ptree; string indent(int level) { string s; for (int i=0; i<level; i++) s += " "; return s; } void printTree (ptree &pt, int level) { if (pt.empty()) { cerr << "/""<< pt.data()<< "/""; } else { if (level) cerr << endl; cerr << indent(level) << "{" << endl; for (ptree::iterator pos = pt.begin(); pos != pt.end();) { cerr << indent(level+1) << "/"" << pos->first << "/": "; printTree(pos->second, level + 1); ++pos; if (pos != pt.end()) { cerr << ","; } cerr << endl; } cerr << indent(level) << " }"; } return; } int main(int, char*[]) { // first, make a json file: string tagfile = "testing2.pt"; ptree pt1; pt1.put("object1.type","ASCII"); pt1.put("object2.type","INT64"); pt1.put("object3.type","DOUBLE"); pt1.put("object1.value","one"); pt1.put("object2.value","2"); pt1.put("object3.value","3.0"); write_json(tagfile, pt1); ptree pt; bool success = true; try { read_json(tagfile, pt); printTree(pt, 0); cerr << endl; }catch(const json_parser_error &jpe){ //do error handling success = false } return success; }

Aquí está la salida:

rcook@rzbeast (blockbuster): a.out { "object1": { "type": "ASCII", "value": "one" }, "object2": { "type": "INT64", "value": "2" }, "object3": { "type": "DOUBLE", "value": "3.0" } } rcook@rzbeast (blockbuster): cat testing2.pt { "object1": { "type": "ASCII", "value": "one" }, "object2": { "type": "INT64", "value": "2" }, "object3": { "type": "DOUBLE", "value": "3.0" } }

Sé que me acerco a impulsar el árbol de propiedades y vi que es una buena característica de las librerías de impulso para la programación en c ++.

Bueno, tengo una duda? ¿Cómo iterar un árbol de propiedades usando iteradores o similares?

En referencia solo hay un ejemplo de navegar por el árbol a través de:

BOOST_FOREACH

Pero ¿no hay nada más? ¿Algo así como un contenedor tipo stl? Sería una mejor solución, hablando de la calidad del código ....


BFS basado en el recorrido de los árboles, se puede usar si queremos realizar una manipulación algorítmica

int print_ptree_bfs(ptree &tree) { try { std::queue<ptree*> treeQ; std::queue<string> strQ; ptree* temp; if (tree.empty()) cout << "/"" << tree.data() << "/""; treeQ.push(&tree); //cout << tree.data(); strQ.push(tree.data()); while (!treeQ.empty()) { temp = treeQ.front(); treeQ.pop(); if (temp == NULL) { cout << "Some thing is wrong" << std::endl; break; } cout << "----- " << strQ.front() << "----- " << std::endl; strQ.pop(); for (auto itr = temp->begin(); itr != temp->end(); itr++) { if (!itr->second.empty()) { //cout << itr->first << std::endl; treeQ.push(&itr->second); strQ.push(itr->first); } else { cout<<itr->first << " " << itr->second.data() << std::endl; } } cout << std::endl; } } catch (std::exception const& ex) { cout << ex.what() << std::endl; } return EXIT_SUCCESS; }


BOOST_FOREACH es solo una forma conveniente de iteración que se puede realizar por iterador, begin () y end ()

Your_tree_type::const_iterator end = tree.end(); for (your_tree_type::const_iterator it = tree.begin(); it != end; ++it) ...

Y en C ++ 11 es:

for (auto it: tree) ...


Me encontré con este problema recientemente y encontré las respuestas incompletas para mi necesidad, por lo que se me ocurrió este breve y dulce fragmento:

using boost::property_tree::ptree; void parse_tree(const ptree& pt, std::string key) { std::string nkey; if (!key.empty()) { // The full-key/value pair for this node is // key / pt.data() // So do with it what you need nkey = key + "."; // More work is involved if you use a different path separator } ptree::const_iterator end = pt.end(); for (ptree::const_iterator it = pt.begin(); it != end; ++it) { parse_tree(it->second, nkey + it->first); } }

Es importante tener en cuenta que cualquier nodo, excepto el nodo raíz, puede contener datos y también nodos secundarios. El if (!key.empty()) obtendrá los datos para todos menos el nodo raíz, también podemos comenzar a construir la ruta para el bucle de los hijos del nodo, si los hubiera.

Comenzaría el análisis llamando a parse_tree(root_node, "") y, por supuesto, debe hacer algo dentro de esta función para que valga la pena hacerlo.

Si está realizando un análisis en el que no necesita la ruta COMPLETA, simplemente elimine la variable nkey y sus operaciones, y solo it->first a la función recursiva.


Una adición a la respuesta ¿Cómo iterar un árbol de propiedades de impulso? :

En el rango de estilo C ++ 11 basado para for (auto node : tree) , cada node es un std::pair<key_type, property_tree>

Considerando que en la iteración escrita manualmente

Your_tree_type::const_iterator end = tree.end(); for (your_tree_type::const_iterator it = tree.begin(); it != end; ++it) ...

El iterador es un puntero a tal par. Es una pequeña diferencia en el uso. Por ejemplo, para acceder a la clave, uno debería escribirla- it->first pero node.first .

Publicado como una nueva respuesta, porque mi edición propuesta a la respuesta original fue rechazada con la sugerencia de publicar una nueva respuesta.