将一个向量拆分为几乎相等的子向量,然后存储到另一个向量中
Posted
技术标签:
【中文标题】将一个向量拆分为几乎相等的子向量,然后存储到另一个向量中【英文标题】:splitting one vector into almost-equal sub vectors then storing into another vector 【发布时间】:2020-08-08 20:37:24 【问题描述】:我正在尝试将一个大型用户给定向量拆分为 x 个子向量。一切“似乎”都按原样工作,但结果不对。
std::vector<std::vector<std::string>> split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount)
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string>> perm_vector;
for (int x = 0; x < thread_amount; x++)
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++)
hm++;
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
perm_vector.push_back(temp_vector);
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
std::cout << perm_vector[0][0];
return perm_vector;
运行此代码将为您提供:
initial size: 7
split amount: 3
2 need to be in each sub-vector
There will be: 1 element remaining
1
2
3
4
5
6
Size of vector holding the sub vectors after splitting: 3
2
我传入的向量叫做test保存字符串,是这样的:
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
直到最后一个 print 语句之前的一切似乎都有效。所以 perm_vector 应该包含 3 个子向量,其中包含主用户给定向量中的每个元素。当您打印 perm_vector[0][0] 时,您会期望输出为“1”,但它是 2,而且 7 也不应该在向量中,6 应该是最后一个,但由于它从 2 开始,所以 7 是在里面。计数器是在函数之外定义的,它从 0 开始。我的问题是为什么它从 2 开始?
【问题讨论】:
hm
在哪里声明和初始化?它不在您发布的代码中。
全局范围定义如下:int hm = 0;
第 172 行的 gremlins 偷走了第一个元素。用minimal reproducible example 证明我错了。
重新考虑使用全局。每次调用split_to_sub_vectors
时,都必须将值重置为零。局部变量听起来更友好。
【参考方案1】:
我在您的代码中发现了两个问题:
hm
在使用前递增。此外,将其设为全球性毫无意义。
size_for_splitting
是整数除法的结果,所以没有余数
我修改了您的代码,以便解决hm
的问题。我得到了预期的输出<<1, 2>, <3, 4>, <5, 6>>
,如上所述缺少7
。
#include <iostream>
#include<vector>
#include<string>
std::vector<std::vector<std::string> > split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount)
std::cout << "initial size: " << initial_vector.size() << std::endl;
int size_for_splitting = initial_vector.size();
std::cout << "split amount: " << thread_amount << std::endl;
int r = size_for_splitting / thread_amount;
std::cout << r << " need to be in each sub-vector" << std::endl;
std::cout << "There will be: " << size_for_splitting % thread_amount << " element remaining" << std::endl;
std::vector<std::vector<std::string> > perm_vector;
int hm = 0;
for (int x = 0; x < thread_amount; x++)
std::vector<std::string> temp_vector;
for (int a = 0; a < r; a++)
std::cout << hm << std::endl;
temp_vector.push_back(initial_vector[hm]);
hm++;
perm_vector.push_back(temp_vector);
std::cout << "Size of vector holding the sub vectors after splitting: " << perm_vector.size() << std::endl;
return perm_vector;
int main()
std::vector<std::string> test;
test.push_back("1");
test.push_back("2");
test.push_back("3");
test.push_back("4");
test.push_back("5");
test.push_back("6");
test.push_back("7");
std::vector<std::vector<std::string> > out = split_to_sub_vectors(test, 3);
【讨论】:
很好的答案,但我们通常会尽量避免为学生做作业。 :) 只是需要练习一下 :) :) 去过那里,做过很多次。欢迎来到 SO! 我不是学生,但我是 C++ 新手 :),太年轻了,不能成为学生。我正在从 python 切换到 c++,我可以使用 numpy 来做到这一点。【参考方案2】:即使 hm 从 0 开始,您在使用它之前也会增加它。可能如果您在内部 for 循环结束时递增,您可能会得到您期望的输出。很难说这个问题,因为我不知道'initial_vector'中有什么,我假设initial_vector[0] = 1?
【讨论】:
@cli 这是正确的答案。您正在跳过initial_vector
的第一个元素。
那么看来你应该在'temp_vector.push_back(initial_vector[hm]);'之后增加hm,否则你会错过索引0
几乎可以肯定是正确的答案,但没有 MRE 作为证据,我坚持我的小精灵小偷的说法。
我刚刚测试过,这确实是修复【参考方案3】:
如果你使用 range-v3 库,实现这个逻辑会变得更容易,而且更不容易出错:
#include <range/v3/all.hpp>
namespace rs = ranges;
namespace rv = ranges::views;
auto split_to_sub_vectors(std::vector<std::string> initial_vector, int thread_amount)
auto res = initial_vector
| rv::chunk(thread_amount)
| rs::to<std::vector<std::vector<std::string>>>;
if (res.back().size() != thread_amount)
res.pop_back();
return res;
这是demo。
【讨论】:
以上是关于将一个向量拆分为几乎相等的子向量,然后存储到另一个向量中的主要内容,如果未能解决你的问题,请参考以下文章
将二进制字符串拆分为长度为 n 的子字符串,然后解码 R 中的每个子字符串
C ++ - 将文本文件作为字符串读取,然后将字符串拆分为向量