[英]Update element stl list of lists
I am working with a list of a list of vector of ints ( std::list<std::list<std::vector<int>>> z(nlevel)
).我正在处理整数向量列表( std::list<std::list<std::vector<int>>> z(nlevel)
)的列表。
I might have something like:我可能有这样的事情:
{ {1} {2} {3} }
{ {1 2} {2 1} {1 3} }
{ {1 2 3} {2 1 3} {1 2 4} }
I need to remove the non-unique combination of integers, so eg, the second element of the list above should become我需要删除整数的非唯一组合,例如,上面列表的第二个元素应该变成
{ { 1 2 } {1 3} }
This is a large object, so I'm trying to update each element of the outermost list by reference.这是一个大对象,所以我试图通过引用更新最外层列表的每个元素。 I've tried something like:我试过这样的事情:
lit = z.begin();
for (i = 0; i < nlevel; i++) {
distinct_z(*lit, primes);
lit++;
}
where distinct_z
is a function to find the unique vector combinations by reference, but this doesn't seem to affect the list z
.其中distinct_z
是通过引用查找唯一向量组合的函数,但这似乎不会影响列表z
。 Note: distinct_z
does work fine in another part of my code where I am already working with the ith element of the list.注意: distinct_z
在我的代码的另一部分工作正常,我已经在处理列表的第 i 个元素。 I've provided distinct_z
below.我在下面提供了distinct_z
。 It includes some unique data types from the Rcpp package in R, but is hopefully understandable.它包含来自 R 中 Rcpp 包的一些独特数据类型,但希望可以理解。 Essentially, I use the log sum of prime numbers to identify non-unique combinations of integers because the order of the integers does not matter.本质上,我使用素数的对数和来识别整数的非唯一组合,因为整数的顺序无关紧要。 To reiterate, distinct_z
does work in another part of my code where I pass it an actual list of vectors of ints.重申一下, distinct_z
确实在我的代码的另一部分工作,我向它传递了一个实际的整数向量列表。 The problem seems to be that I'm trying to pass something using an iterator.问题似乎是我试图使用迭代器传递一些东西。
void distinct_lz(std::list<std::vector<int>> &lz,
const IntegerVector &primes) {
int i, j, npids = lz.size();
NumericVector pids(npids);
std::list<std::vector<int>>::iterator lit = lz.begin();
int z_size = lit -> size();
for(i = 0; i < npids; i++) {
for (j = 0; j < z_size; j++) {
// cprime = primes[lit -> at(j)];
// pids[i] += log(cprime);
// cprime = primes[lit -> at(j)];
pids[i] += log(primes[lit -> at(j)]);
}
lit++;
}
LogicalVector dup = duplicated(round(pids, 8));
lit = lz.begin();
for(i = 0; i < npids; i++) {
if(dup(i) == 1) {
lz.erase(lit);
}
lit++;
}
}
What is the best approach for doing what I want?做我想做的事的最佳方法是什么?
Background: The data structure probably seems unnecessarily complicated, but I'm enumerating all connected subgraphs starting at a vertex using a breadth-first approach.背景:数据结构可能看起来不必要地复杂,但我正在使用广度优先方法枚举从顶点开始的所有连接子图。 So given a current subgraph, I see what other vertices are connected to create a set of new subgraphs and repeat.因此,给定一个当前子图,我会看到连接了哪些其他顶点以创建一组新子图并重复。 I initially did this using a list of vectors of ints, but removing repeats was ridiculously slow due to the fact that I had to copy the current object if I removed part of the vector.我最初使用整数向量列表来完成此操作,但由于如果删除部分向量,我必须复制当前对象,因此删除重复项的速度非常慢。 This approach is much faster even though the structure is more complicated.尽管结构更复杂,但这种方法要快得多。
Edit: Here is a solution that mostly does what I want, though it results in some undesired copying.编辑:这是一个解决方案,主要是我想要的,尽管它会导致一些不需要的复制。 I updated distinct_z
to return a copy of the object instead of modifying the reference, and then replaced the element at lit
.我更新了distinct_z
以返回对象的副本而不是修改引用,然后替换了lit
处的元素。
lit = z.begin();
for (i = 0; i < nlevel; i++) {
(*lit) = distinct_z(*lit, primes);
lit++;
}
In C++ there is a well known idiom known as the erase-remove idiom for removing elements from an STL container.在 C++ 中有一个众所周知的习惯用法,称为擦除-删除习惯用法,用于从 STL 容器中删除元素。 It basically involves shuffling unwanted items to the end of the container and then erasing the unwanted tail.它基本上涉及将不需要的项目拖到容器的末端,然后擦除不需要的尾部。
We can use a predicate function (eg lambda) to select the items we want to erase and use functions from <algorithm>
.我们可以使用谓词函数(例如 lambda)来选择我们想要删除的项目并使用<algorithm>
函数。 In your case we use a set of set of ints ( std::<set<int>>
) to store unique combinations.在您的情况下,我们使用一组整数( std::<set<int>>
)来存储独特的组合。 Convert each vector in the list to a set of ints and delete it if hasn't been seen before.将列表中的每个向量转换为一组整数,如果以前没有见过,则将其删除。
#include <set>
#include <list>
#include <vector>
#include <algorithm>
#include <iostream>
void distinct_lz(std::list<std::vector<int>>& lz)
{
std::set<std::set<int>> unqiueNums;
lz.erase(std::remove_if(lz.begin(), lz.end(),
[&unqiueNums](std::vector<int>& v) {
std::set<int> s{ v.cbegin(), v.cend() };
if (unqiueNums.find(s) != unqiueNums.end())
return true;
else
{
unqiueNums.insert(s);
return false;
}
}), lz.end());
}
int main()
{
std::list<std::vector<int>> lv = { {1, 2}, {2, 1}, {1, 3}, {3,4} };
distinct_lz(lv);
for (auto &v: lv)
{
for( auto n: v)
{
std::cout << n << " ";
}
std::cout << "\n";
}
}
Output:输出:
1 2 1 2
1 3 1 3
3 4 3 4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.