From bbaaaeb30d74e1ef339784f7f7d2eba8d3d9a8b1 Mon Sep 17 00:00:00 2001 From: torin <torin@git.sch.bme.hu> Date: Mon, 25 May 2015 23:59:22 +0200 Subject: [PATCH] =?UTF-8?q?=C3=B6sszerakva=20a=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.cpp | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 188 insertions(+), 6 deletions(-) diff --git a/main.cpp b/main.cpp index e3d1e4b..91f74f7 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,146 @@ #include <memory> #include <vector> +namespace recursive_storage{ +template<class T> +class node +{ +private: + + T t; + const int ID; + static int _id; + std::vector<std::shared_ptr<node<T>>> _childs{}; + std::vector<std::weak_ptr<node<T>>> _bad_childs{}; + +public: + + node()=delete; + + node(T&& t):t(std::move(t)),ID(_id++){} + + node( const T& t):t(t),ID(_id++){} + + T& data() { return t; } + + int id() { return ID; } + + std::shared_ptr<node<T>>* get_original(node<T>& t) + { + for(auto& i: _childs) + if(i->id() == t.id()) + return &i; + return nullptr; + } + + std::vector<node<T>*> childs() + { + std::vector<node<T>*> ret{}; + for(auto& it : _childs) + ret.push_back(&(*it)); + for(auto& it : _bad_childs) + ret.push_back(&(*(it.lock()))); + return ret; + } + + std::vector<node<T>*> inf_round_childs() + { + std::vector<node<T>*> ret{}; + for(auto& it : _bad_childs) + ret.push_back(&(*(it.lock()))); + return ret; + } + + std::vector<node<T>*> safe_childs() + { + std::vector<node<T>*> ret{}; + for(auto& it : _childs) + ret.push_back(&(*it)); + return ret; + } + + void erase_child(node<T>& t) + { + for(auto it= std::begin(_childs);it!=std::end(_childs);it++) + if((*it)->id() == t.id()) + _childs.erase(it); + + for(auto it= std::begin(_bad_childs);it!=std::end(_bad_childs);it++) + if((*it).lock()->id() == t.id()) + _bad_childs.erase(it); + } + + void flow_after(std::function<bool(node<T>&)> funct) + { + if (funct(*this)) + return; + for(auto& child : _childs) + child->flow_after(funct); + } + + void flow_before(std::function<bool(node<T>&)> funct) + { + for(auto& child : _childs) + child->flow_before(funct); + if (funct(*this)) + return; + } + + node<T>& add_child(node<T>* w) + { + if(w==this) + return *this; + + bool found=false; + auto& me=*this; + w->flow_after([&found,&me](node<T>& t){if(&t==&me) found=true; return found;}); + if (!found) + { + _childs.push_back(std::make_shared<node<T>>(*w)); + } + else + { + std::shared_ptr<node<T>>* fo=nullptr; + w->flow_after([&me,&fo](node<T>& t){ fo=t.get_original(me); if(fo!=nullptr) return true; }); + _bad_childs.push_back(std::weak_ptr<node<T>>{*fo}); + } + return *this; + } + + node<T>& add_child(node<T>& w) + { + return add_child(&w); + } + + node<T>& add_child(const T& t) + { + _childs.push_back(std::make_shared<node<T>>(node<T>{t})); + return *this; + } + +}; + +template<class T> +int node<T>::_id=0; + +template<class T> +class graph +{ +private: + static void erase(node<T>& root , node<T>& to_del) + { + root.flow_after([&to_del](node<T>& t){ int i= t.childs().size(); t.erase_child(to_del); if(i>t.childs().size()) return true; return false; }); + } + +public: + static void erase(node<T>& root , node<T>* t) + { + erase(root,*t); + } +}; +} + +namespace local_storage{ template<class T> class graph { @@ -77,7 +217,13 @@ public: if(!foundn || !foundo) return; - connections.push_back(connection{n.id(),o.id()}); + bool foundround=false; + int id=n.id(); + flow_after(o,[&id,&foundround](node& n){if(n.id()==id) foundround=true;}); + if(!foundround) + connections.push_back(connection{n.id(),o.id()}); + else + weak_connections.push_back(connection{n.id(),o.id()}); } void erase(node& n) @@ -122,6 +268,26 @@ public: if(re.id()==i.A) ret.push_back(&re); } + for(auto& i : weak_connections) + { + if(n.id()==i.A) + for(auto& re:nodes) + if(re.id()==i.A) + ret.push_back(&re); + } + return ret; + } + + std::vector<node*> get_inf_round_childs(node& n) + { + std::vector<node*> ret{}; + for(auto& i : weak_connections) + { + if(n.id()==i.A) + for(auto& re:nodes) + if(re.id()==i.A) + ret.push_back(&re); + } return ret; } @@ -160,20 +326,36 @@ public: } }; - template<class T> int graph<T>::node::_id=0; +} + +void test() +{ + std::vector<recursive_storage::node<int>> a; + for(int i=0;i<1000000;i++) + a.push_back(recursive_storage::node<int>{5}); + a[0].add_child(int{6}); + a[0].childs()[0]->add_child(int{7}); + a[0].childs()[0]->add_child(int{8}); + auto to_del = a[0].childs()[0]->childs()[0]; + a[0].childs()[0]->add_child(a[0]); + a[0].flow_after([]( recursive_storage::node<int>& elem ){ std::cout<<"inf rounds from here:"<<elem.inf_round_childs().size()<<" .id:"; std::cout<< elem.id() << ":" << elem.data() <<std::endl; return false; }); + recursive_storage::graph<int>::erase(a[0],to_del); + a[0].flow_after([]( recursive_storage::node<int>& elem ){ std::cout<<"inf rounds from here:"<<elem.inf_round_childs().size()<<" .id:"; std::cout<< elem.id() << ":" << elem.data() <<std::endl; return false; }); +} int main() { - graph<int> g{}; + local_storage::graph<int> g{}; g.add_node(6); auto& t2=g.add_node(6); - std::cout<<"ha"<<std::endl; auto& t = g.add_node(52); g.connect(g[0],t); g.connect(g[0],t2); - std::cout<<std::endl<<g.get_childs(t).size()<<std::endl; - g.flow_before(g[0],[](graph<int>::node& a){std::cout<<a.data()<<":"<<a.id()<<std::endl;}); + g.connect(t2,g[0]); + std::cout<<std::endl<<g.get_childs(t2).size()<<std::endl; + g.flow_before(g[0],[](local_storage::graph<int>::node& a){std::cout<<a.data()<<":"<<a.id()<<std::endl;}); + test(); return 0; } -- GitLab