0

我有一个递归函数find(),它试图找到具有给定 ID 的项目。下面我将类中的相关部分提取出来,做一个编译示例:

#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到它们中。现在我希望能够查找一个项目的 ID 并使用递归find()方法返回找到的项目或子项目对象。如果我使用addSubitems()(带有变量 args)添加项目,它将找到该项目但不返回(有效)项目对象。如果我通过传递项目向量来使用 addSubitems 方法,则 find() 方法不会完全递归所有子项目。

实际上,在过去的 4 个小时里,我一直在解决这个问题,而且我没有想法,这可能是我监督或错过的一件简单的事情。我添加了复制构造函数 / 和赋值运算符后记(只是为了看看行为是否有变化),但没有。不用担心item ID是字符串类型(原因是为了后面的序列化),这个类还处于早期阶段,所以我现在选择了字符串类型。

有人可以指出我的缺陷/问题以使这门课变得直截了当!提前非常感谢!

4

1 回答 1

0

好吧,“它会找到项目但不返回(有效)项目对象”的一个问题。是:

您将 Item* 发送到 addSubItems 方法,然后将 (*Item) 添加到向量;这将初始化一个副本 c'tor,所以稍后,当您执行 is &c == &c3 时,显然这是错误的,因为虽然对象确实相同,但地址不会是因为它们是彼此的副本。

并不是说我理解您为什么要复制,但解决方案是测试

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

或分配成员,保存一个

std::vector<Item*> subitems;

然后问if (c == c3) -> asking about the addresses

于 2013-04-05T09:22:22.097 回答