Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在类对象的指针中拖动指针,并递归地分配它们,然后返回指针?C++;_C++_Pointers_Recursion - Fatal编程技术网

C++ 如何在类对象的指针中拖动指针,并递归地分配它们,然后返回指针?C++;

C++ 如何在类对象的指针中拖动指针,并递归地分配它们,然后返回指针?C++;,c++,pointers,recursion,C++,Pointers,Recursion,假设如下: 我有一个叫做Person的类: 班级人员{ 公众: 人(); ~Person(); int compare(const Person&compared);//使用strcmp()比较名称 void display(); 受保护的: 字符*名称; 智力年龄; };一旦你意识到一个简单的事实,答案就非常简单了。假设在给定的迭代中,nmatches为0,并且您发现了一条compare()声明与目标匹配的记录 这意味着这是第一条匹配记录。这意味着,在返回的数组中,此匹配将进入perso

假设如下:

  • 我有一个叫做
    Person
    的类:
班级人员{
公众:
人();
~Person();
int compare(const Person&compared);//使用strcmp()比较名称
void display();
受保护的:
字符*名称;
智力年龄;

};一旦你意识到一个简单的事实,答案就非常简单了。假设在给定的迭代中,nmatches为0,并且您发现了一条
compare()
声明与目标匹配的记录

这意味着这是第一条匹配记录。这意味着,在返回的数组中,此匹配将进入
persons[0]

如果nmatches为1,则表示此匹配将进入
人员[1]
,依此类推

这意味着,这变得简单:

Person * Linked_List::retreive(Person target, Node * current, int & matches) {
    if (current == NULL) {
        Person * persons = new Person[matches];
        return persons;
    }
    if (target.compare(current->getData()) == 0) {
        int n=matches;

        auto p=retreive(target, current->getNext(), ++matches);
        p[n]=current->getData();
        return p;
    }
    return retreive(target, current->getNext(), matches); //recursive call
}

就这样。然而,你的家庭作业是去掉难看的
新的
,然后用
std::vector
重写整个过程。用现代C++,很少需要手动<代码>新< /COD>和<代码>删除< /代码>任何东西。每个需求和愿望都有一个容器,而且,作为额外的奖励,当容器被正确使用时,不会有任何内存泄漏。真便宜

此示例使用
std::vector
作为临时缓存,并且除了指针数组之外,还将此向量返回给用户。我的操作假设Node::getData()返回指向数据元素的指针。(相当确定,这是相当标准的做法。)您还可以将返回类型更改为void,从而完全消除对数组的需要,因为您还可以获得包含数据的std::vector的返回。(由于STL容器的多功能性,使用带有
new
/
delete
的数组已经过时了。)

请注意,变量
int&matches
现在包含在
std::vector::size()

Person*链接列表::检索(Person-target、Node*current、std::vector&\u-persons){
如果(当前==NULL){
Person*persons=新人[_persons.size()];
对于(int i(0);i<_persons.size();++i)
{
人(i)=&u人(i);;
}
返回人员;
}
if(target.compare(current->getData())==0){
_persons.push_back(当前->获取数据());
return retrieve(target,current->getNext(),_persons);//递归调用
}
return retrieve(target,current->getNext(),_persons);//递归调用
}

您是否考虑过使用动态迭代容器来存储人员?(例如
std::vector
或类似的实现)那么您就不需要在列表中重复两次首先计算他们,然后返回一个正确的人数组。@ChrisBritt我实际上没有遍历两次,这就是为什么这是一个有点挑战性的问题。谢谢,我会考虑你的建议。但是,出于好奇,我会等着看我的问题是否有解决方案。只是好奇,
compare
如果匹配,则返回0,并且!0表示不匹配?(您是否正在从中传递其他信息?如果不是,您可能希望使用bool以提高可读性。)0如果相等,-1如果较小,1如果较大。与strcmp()函数相同@克里斯布里蒂编写了一个使用向量作为临时缓存的版本。如果你感兴趣,我可以把它寄出去。当它通过引用传递向量时,它的开销不会高得多,并且提供了一种在迭代结束时分配值的干净方法。(山姆已经给出了一个很好的答案,我想我应该先问。)
Person * Linked_List::retreive(Person target, Node * current, std::vector<Person*>& _persons) {
    if (current == NULL) {
        Person * persons = new Person[_persons.size()];
        for(int i(0); i < _persons.size(); ++i)
        {
            persons[i] = &_persons[i];
        }
        return persons;
    }
    if (target.compare(current->getData()) == 0) {
        _persons.push_back(current->getData());
        return retreive(target, current->getNext(), _persons); //recursive call
    }
    return retreive(target, current->getNext(), _persons); //recursive call
}