2013-04-05 1 views
0

주어진 ID로 항목을 찾으려고하는 재귀 함수 find()이 있습니다. 재귀 함수가 개체/하위 개체를 완전히 되풀이하지 않습니다

#include <iostream> 
#include <cstdarg> 
#include <cstdio> 
#include <string> 
#include <vector> 

class Item { 
private: 
    std::vector<Item> subitems; 

public: 
    std::wstring id; 

public: 
    Item() 
    : subitems(0), id(L"") {} 

    Item(const Item& rhs) 
    : subitems(rhs.subitems.size()) { 
     for (std::size_t i = 0; i < rhs.subitems.size(); ++i) 
      subitems[i] = rhs.subitems[i]; 
     id = rhs.id; 
    } 

    Item& operator==(const Item& rhs) { 
     if (this != &rhs) { 
      for (std::size_t i = 0; i < rhs.subitems.size(); ++i) 
       subitems[i] = rhs.subitems[i]; 
      id = rhs.id; 
     } 
     return *this; 
    } 

    std::vector<Item> getSubitems() { 
     return subitems; 
    } 

    Item addSubitems(Item * item ...) { 
     va_list args; 
     va_start(args, item); 
     for (Item * arg = item; arg != NULL; arg = va_arg(args, Item *)) { 
      subitems.push_back(*item); 
     } 
     va_end(args); 

     return *this; 
    } 

    Item addSubitems(std::vector<Item>& items) { 
     for (typename std::vector<Item>::value_type &item : items) { 
      subitems.push_back(item); 
     } 

     return *this; 
    } 

    static Item * find(int id, std::vector<Item>& items) { 
     std::wstring id_str = std::to_wstring(id); 
     std::wcout << "--> find id=" << id_str << std::endl; 
     std::wcout << "size of items=" << items.size() << std::endl; 
     for (typename std::vector<Item>::value_type &c : items) { 
      std::wcout << "it .. cur id=" << c.id << std::endl; 
      if (!c.id.empty() && c.id == id_str) { 
       std::wcout << "==> found" << std::endl; 
       return &c; 
      } 

      if (!(c.getSubitems()).empty()) { 
       std::wcout << "-> find " << id << " in subitems" << std::endl; 
       std::vector<Item> subcls = c.getSubitems(); 
       std::wcout << "size of subitems=" << subcls.size() << std::endl; 
       Item * sub = find(id, subcls); 
       if (sub != NULL) { 
        std::wcout << "==> found in subitems" << std::endl; 
        return sub; 
       } 
      } 
     } 
     return NULL; 
    } 
}; 

int main() { 
    Item c1; 
    c1.id = L"0"; 
    Item c2; 
    c2.id = L"1"; 
    Item c3; 
    c3.id = L"2"; 
    Item c4; 
    c4.id = L"3"; 
    //std::vector<Item> cll4({c4}); 
    //std::vector<Item> cll3({c3}); 
    //std::vector<Item> cll2({c2}); 

    c3.addSubitems(&c4, NULL); 
    c2.addSubitems(&c3, NULL); 
    c1.addSubitems(&c2, NULL); 

    //c1.addSubitems(cll2); 
    //c2.addSubitems(cll3); 
    //c3.addSubitems(cll4); 

    std::vector<Item> items({c1}); 

    Item * c = Item::find(2, items); 
    std::wcout 
     << "Found item=" 
     << ((c != NULL && c == &c3) ? "true" : "false") << std::endl; 
    std::wcout 
     << ((c != NULL) ? c->id : L"") << std::endl; 

    return 0; 
} 

내가 Items 몇을 만들고 그들에게 sub-Items를 추가 : I 클래스에서 관련 부분을 추출 아래의 예를 컴파일 할 수 있도록합니다. 이제 재귀적인 find() 메서드를 사용하여 항목의 ID를 조회하고 발견 된 항목 또는 하위 항목 개체를 반환 할 수 있기를 원합니다. addSubitems() (변수 args 포함) 항목을 추가하면 항목을 찾을 수 있지만 (유효한) 항목 개체는 반환하지 않습니다. 항목의 벡터를 전달하여 addSubitems 메서드를 사용하면 find() 메서드가 완전히 모든 하위 항목을 반복하지 않습니다.

실제로 저는 지난 4 시간 동안이 문제에 실제로 착수했습니다. 아이디어가 부족합니다. 내가 간과하거나 놓친 간단한 것일 수 있습니다. 복사 생성자/대입 연산자를 afterwords에 추가했는데 (동작이 변경되었는지 확인하기 위해), 아니요. 아이템 ID가 문자열 타입 인 것에 대해 걱정할 필요가 없습니다 (이유는 나중에 직렬화하기 때문에),이 클래스는 초기 단계이므로 지금은 문자열 유형을 선택했습니다.

누군가가 내게 결함/클래스를 똑바로 얻으려고 문제를 지적하시기 바랍니다 수 있습니다! 미리 감사드립니다.

답변

0

글쎄, "항목을 찾을 수 있지만 (유효한) 항목 개체를 반환하지 않습니다."라는 문제가 하나 있습니다. :

Item *을 addSubItems 메서드에 보낸 다음 벡터에 (* Item)을 추가합니다. 이것은 복사본을 초기화 할 것이므로, 나중에 & c == & c3이 될 때, 분명히 거짓 일 것입니다. 왜냐하면 객체는 INDEED와 동일하지만 주소는 복사되지 않기 때문입니다 다른. 복사 할 것이지만,이 솔루션은 하나 테스트

if (c == c3) -> activating the Item operator == 

에이거나

std::vector<Item*> subitems; 

을 저장, 회원을 할당하고 요청 이유

은 이해하지 않는 것이 if (c == c3) -> asking about the addresses

+0

의견을 보내 주셔서 감사합니다. 네, 실제로, 당신의 대답을 읽은 후에 그것은 나에게 분명하게 들립니다. 지금은 옵션 번호 2 (포인터 벡터)를 사용합니다. 비록 내가 그다지 만족스럽지는 않지만, 개발하는 동안 몇 가지를 바꿀 수도 있습니다. –

+0

할당했는지 확인하십시오. – Alon

관련 문제