从给定矢量的块中生成一个新矢量
Generate a new vector out of blocks of a given vector
我有一个std::vector
,其中存储了大约100万个值。现在我想将向量划分为给定大小的N个块,并通过从原始向量中随机抽取N个块来创建新的std::vector
。这是我到目前为止所拥有的,这只是为了得到一个想法。
int main {
int breakPoint = 2;
std::vector<int> test = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> newTest;
int length = test.size();
for (size_t i = 0; i < length; i++) {
int foo = random(breakPoint,length);
//std::cout << foo << std::endl;
std::vector<int> subvector(test.begin() + foo, test.begin() + foo + breakPoint);
for (size_t i = 0; i < subvector.size(); i++){
newTest.push_back(subvector[i]);
}
}
return 0;
}
int random(int N, int interval){
int rnd;
int foo = 1;
while (foo !=0) {
rnd = int(randomNumber(0, (interval+1-N)));
foo = (rnd%N);
}
return rnd;
}
randomNumber(a,b)
在区间中给出一个随机数[a,b)。这段代码运行,对于不太大的向量,我会这样使用它。但由于我有一个很大的原始向量,为了获得统计数据,我必须多次重复这个新的向量操作,所以我宁愿不使用它。所以我的问题是,如何使这样的操作非常快?第一个问题显然是如何在random()
中选择断点。谢谢你帮我,干杯!
正如评论所建议的,对于一个非常大的test
,此代码将在复制过程中陷入困境,解决方案是不复制。(假设测试包含一百万个元素,这意味着你将进行400万次随机访问来复制。)
只要test
保持不变,将迭代器保持到中是索引到test
的简单方法。
const auto breakPoint = 2;
const std::vector<int> test = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<vector<int>::const_iterator> newTest(test.size());
for(auto& i : newTest){
i = test.begin() + random(breakPoint, test.size());
}
将迭代器保持在一个向量中允许我们在访问内存之前对它们进行排序。因此,我们可以利用缓存的空间局部性。
sort(newTest.begin(), newTest.end());
现在要使用newTest
,您可以执行以下操作:
for(auto& i : newTest){
for_each(i, i + breakPoint, [](int foo){cout << foo << ' ';});
cout << endl;
}
编辑:
random
在总体方案中似乎不是一个巨大的时间消耗,因为它不进行内存访问,但你可以通过搜索合适的breakPoint
乘法器来改进它,而不是试图随机找到breakPoint
增量:
// This change assumes that you've already done srand(time(nullptr));
int random(int N, int interval){
return (rand() % (interval / N)) * N;
}
您可以看到如此简单的东西是如何内联的,这将提供允许interval / N
只计算一次的进一步好处。所以我们的初始化部分现在可以变成:
const auto breakPoint = 2;
const std::vector<int> test = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const auto partitions = test.size() / breakPoint;
vector<vector<int>::const_iterator> newTest(test.size());
srand(time(nullptr));
for(auto& i : newTest){
i = test.begin() + breakPoint * (rand() % partitions);
}
如何使用std::vector::insert将随机块附加到输出向量:
std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> output;
for (size_t i = 0; i != num_blocks; i++) {
int block_position = getRandomBlock(num_blocks, block_length);
auto block_begin = input.cbegin() + block_position;
auto block_end = block_begin + block_length;
output.insert(output.end(), block_begin, block_end);
}
相关文章:
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 如何使用CLion在Mac上创建一个新的.txt文件
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 矢量如何将数据复制到另一个矢量?
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 将一个 QWidget 链接到另一个新创建的 QWidget
- r-在Rcpp和C++之间转换矢量(使用Rcpp::as或Rcpp:::wrap)是否会创建一个新的矢量并复制元素
- 如何在OpenCV中存储部分轮廓点喜欢新矢量中的左侧,该类型为<vector<vector<Point>>
- C++:初始化(新)一个不同初始大小的向量数组
- 新的一个一维阵列,非常大,例如60000*60000
- 矢量填充比创建新矢量慢
- 如何使用范围 v3 将矢量转换为新矢量
- 从给定矢量的块中生成一个新矢量
- 为什么我可以使用一个大的缓冲区作为一个矢量,而不是与Windows上的新
- 将一个矢量写入一个新的文本文件
- 将文本文件的内容一个字符一个字符地读入矢量,不跳过空白或新行
- 将void指针的两个矢量(void*)合并到生成的新矢量中