根据条件C ++复制矢量元素

时间:2015-05-29 20:48:57

标签: c++ automata

我使用C ++创建了Hopcroft的DFA最小化算法。

霍普克罗夫特算法的一部分是 - 最初 - 划分两组(P表示接受和非接受状态,Q表示只有非接受状态)。我已经有了P组,并且从P I尝试提取Q.我使用以下代码来执行此操作:

for(int i=0; i<groupP.size(); i++)
    if(groupP[i]->final)
        groupQ.push_back(groupP[i]);

其中groupP和groupQ是:

vector<node*> groupQ;
vector<node*> groupP;

和node是我创建的结构,用于表示我的自动机的节点。它保证了布尔属性&#34; final&#34;已经正确设置(对于非最终状态为false,对于最终状态为true)。

最后,我的问题是:通过做我做过的事情,将一个元素从一个向量复制到另一个元素是否正确?如果我从groupP修改复制元素的内容,那么同样的元素也会在groupQ中被修改吗?

2 个答案:

答案 0 :(得分:3)

现在,你有指针的向量。当您从一个向量复制到另一个向量时,您将复制指针,而不是元素本身。

由于您有两个指向同一节点的指针,因此对节点所做的任何修改都将在另一个组中可见 - 即,如果您对groupP[i]->foo进行了更改,则会看到相同的更改在groupQ[j]->foo中(前提是groupP[i]是您从groupP复制到groupQ的其中一个元素。

如果你不想那样,你有几个选择。一种方法是将groupPgroupQ保留在同一个向量中,但根据元素final成员的状态对向量进行分区:

auto P_end = std::partition(groupP.begin(), groupQ.end(), 
                              [](node *n) { return n->final;});

然后[groupP.begin(),P_begin)是groupP(即final==true)而[P_begin,groupP.end())是groupQ(即final==false)。

这会移动指针(并给你一个迭代器,所以你知道两者之间的分界线)所以你只有一个指向每个元素的指针,但它们被分成两个相关的组。

作为最后一种可能性,您可能希望实际将元素从groupP复制到groupQ,并在此过程中创建新元素,因此将项目从groupP复制到{ {1}},您现在复制的每个项目都存在于两个位置 - 即groupQ中有一个元素,groupP中有一个元素。任何一个都可以修改,但它们彼此分开,所以要么可以修改,要么修改一个对另一个没有影响。

实现这一目标最明显的方法是使用节点向量:

groupQ

这样,当您从一个组复制到另一个组时,您将复制节点本身而不是指向节点的指针,因此每个副本都会创建一个与现有节点具有相同值的新的独立节点。

答案 1 :(得分:1)

你可以使用std::copy_if做同样的事情:

std::copy_if(groupP.cbegin(), groupP.cend(),
             std::back_inserter(groupQ),
             [](node* n){ return n->final; });

由于您正在操作指针,因此元素本身是共享的,因此可以从另一个容器中看到修改其中一个容器中的节点。

请注意,像您一样操作原始指针非常容易出错,例如,您可能希望使用shared pointers

修改:添加缺失的std::back_inserter