2013-05-22 28 views
5

Bir sınıf Foo'm var diyelim. Foo tipi bir vektör içerir. foo içinde vektör yinelemek için bir döngü yazmak ve biz vektörlerin üzerinde nerede bir seviyeye ulaşana kadar sürekli alt vektörler yinelemek Nasıl yinelemenize yapabilirsinizVektördeki tüm alt vektörler arasında nasıl yineleme yapılır?

class Foo 
{ 
    Foo(); 
    std::vector<Foo> foos; 
} 

boştur, ama nasıl Vektörün boş olduğu bir seviyeye ulaşıncaya kadar orijinal vektör içindeki foo nesnelerini vektörler boyunca yinelemeli olarak yineliyorum.

Foo f; 
if(!f->foos.empty()) 
{ 

    std::vector<Foo>::const_iterator itr; 

    for (itr = f.foos.begin(); itr!=f.foos.end(); ++itr) 
    { 
    } 
} 
+0

Eğer Foo'nun bir Foos'u varsa, oradaki özyineleşmiş doğası nedeniyle bir yığın taşması olacaktır. Bar'ın bir vektörünün olmadığından emin misin? –

+0

@ChristopherBales haklı, bu DataStructure aslında bir Ağaç uygular ... – Exceptyon

+1

Gönderilen kod yasadışıdır ve g ++ ve her zamanki seçeneklerle derlemez ('-D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC' de dahil olmak üzere) zor hatalara davranış. –

cevap

8

Kullanım özyineleme:

class Foo 
{ 
    Foo(); 
    std::vector<Foo> foos; 

    void iterate() 
    { 
     std::vector<Foo>::const_iterator itr; 

     for (itr = foos.begin(); itr!=foos.end(); ++itr) 
     { 
      // do stuff breadth-first 
      (*itr).iterate(); 
      // do stuff depth-first 
     } 
    } 
} 
+0

-1: Zeki, ancak yineleme, üretim düzeyi kodunda nadiren bir yere sahiptir. –

+0

@JohnDibling Tamamen gereksinimlere bağlıdır. Aslında, çoğu zaman iyi (üretim seviyesi) bir çözümdür. – leemes

+0

Yorumlarınız burada, bu noktalar BFS ve DFS siparişinde ziyaret edilmez. Her ikisi de, özyinanın doğası gereği DFS'dir. Özyineleme * * DFS'dir. Kodunuzdaki ikinci nokta, "geri izleme" olarak da adlandırılan çocuk düğümlerini ziyaret ettikten * sonra. BFS genellikle bir yığın yerine bir sıra kullanır (bu, yinelemeli olarak kullanıldığında örtük olarak kullanılır). – leemes

2

bir kuyruk kullanın:

std::deque<Foo> q; 
q.push_back(f); 
while (!q.empty()) { 
    Foo curr = q.back(); 

    typedef std::vector<Foo>::iterator iter; 
    iter end = curr.foos.end(); 
    for(iter it = curr.foos.begin(); it != end; ++it) { 
     if(!it->empty()) { 
      q.push_back(*it); 
      continue; 
     } 
     // do stuff with *it 
    } 

    q.pop_back(); 
} 
+0

Yinelemeli çözüm daha basittir. –

+0

@JamesKanze Recursion normalde daha basit bir çözüm sunar ancak yığın boşluğunuz yoksa programın çökmesi riski her zaman vardır. – andre

+0

Gerekli yığına sahip değilseniz, programın çökmesi riski vardır. Programlama hatası yaparsanız programın çökme riski vardır; bu, seçtiğiniz çözüm daha karmaşıksa daha olasıdır. –

0

Sizin Foo nesneleri bir ağaç veri yapısını oluşturur. Ağaçtaki konumunuzu takip etmek için kökten bir düğüme, herhangi bir yolu std::stack<Foo*> olarak temsil edebilirsiniz. Bu fikri ve derinlemesine ilk arama özelliğini kullanarak, yineleme kullanmadan Foo nesnesinin tamamını ziyaret etme işleminizi gerçekleştirebilirsiniz.

İlgili konular