如何在 C++ 中将 load/read 二进制文件转换为 "vector<vector< bitset<32> >"?
How to load/read binary file into an "vector<vector< bitset<32> >" in c++?
我对 loading/reading 和
有疑问
vector<vector< bitset<32> >
(called/typedef在我的代码中作为人口)
它使用以下代码存储:
void genetic_algorithm::save_generation(population pop_to_save, string filename){
std::ofstream file(filename, std::ofstream::binary);
unsigned long n;
for(size_t i = 0; i < pop_to_save.size(); i++ )
{
if ( pop_to_save[i].size() > 0 )
{
n = pop_to_save[i][0].to_ulong();
const char* buffer = reinterpret_cast<const char*>(&n);
file.write(buffer, pop_to_save[i].size());
}
}
}
因此我需要的是一个可以加载的函数,即:
population genetic_algorithm::load_generation(string filename){
// TODO
}
此致,
马蒂亚斯。
编辑
我自己解决了这个问题(在评论的帮助下)
这是可能面临相同问题的任何人的最终代码:
void genetic_algorithm::save_generation(population pop_to_save, string filename){
std::ofstream file(filename, std::ofstream::binary);
unsigned long n;
for(size_t i = 0; i < pop_to_save.size(); i++ ) {
for (size_t j = 0; j < pop_to_save[i].size(); j++) {
n = pop_to_save[i][j].to_ulong();
file.write(reinterpret_cast<const char*>(&n), sizeof(n));
}
}
std::cout << "Saved population to: " << filename << '\n';
}
population genetic_algorithm::load_generation(string filename){
std::ifstream file(filename, std::ofstream::binary);
population loaded_pop (20, std::vector<bitset<32>> (394,0));
unsigned long n;
for(size_t i = 0; i < 20; i++ ) {
for (size_t j = 0; j < 394; j++) {
file.read( reinterpret_cast<char*>(&n), sizeof(n) );
loaded_pop[i][j] = n;
}
}
std::cout << "Loaded population from: " << filename << '\n';
return loaded_pop;
}
我检查了你的方法 genetic_algorithm::save_generation()
,这是我发现的:
bitset<32>
以压缩形式存储 32 位(可能是 unsigned int
和 32 位或类似的东西)。
vector<bitset<32> >
存储此类位集的动态数组。
vector<vector<bitset<32> > >
存储这样的位集动态数组的动态数组。
到目前为止,还不错。在您的方法 genetic_algorithm::save_generation()
中,您循环遍历外部向量的所有元素以转储每个内部向量的内容(如果不为空)。
file.write(buffer, pop_to_save[i].size());
可能不是您想要的。第二个参数。 of std::ostream::write()
是字符数。你传递了 resp 的 size()
。 returns 元素数量(但不是字节大小)的内部向量。但是元素大小 (bitset<32>
) 可能比一个字符大。更好的方法(虽然不是最好的)是使用 file.write(buffer, 4 * pop_to_save[i].size());
。 (sizeof (char)
:1,sizeof bitset<32>
:希望是 4,但我会检查一下。)
因此,使用 file.write(buffer, pop_to_save[i].size() * sizeof pop_to_save[i][0]);
更安全。这更好,但仍然不完美。如果你想在多个平台上使用你的应用程序,这可能会失败,因为文件格式现在变得依赖于平台。 (取决于sizeof pop_to_save[i][0]
。)
因此,最好的方法是也为内部向量创建一个嵌套循环,并使用一种平台独立大小(例如 std::uint32_t
)单独存储它们的元素。
然而,我真正关心的是设计问题:
如果您存储动态数组的动态数组(其中每个内部数组可能是任意大小),那么您还必须存储这些内部数组的元素数量。这就是我想念你的方法 genetic_algorithm::save_generation()
.
可能是,您的加载问题是由于您必须为要加载的位保留或调整内部向量的大小但您不知道大小。我的回答是:你不可能知道。此信息丢失(必须以某种方式提供,例如由文件本身提供)。
我对 loading/reading 和
有疑问vector<vector< bitset<32> >
(called/typedef在我的代码中作为人口)
它使用以下代码存储:
void genetic_algorithm::save_generation(population pop_to_save, string filename){
std::ofstream file(filename, std::ofstream::binary);
unsigned long n;
for(size_t i = 0; i < pop_to_save.size(); i++ )
{
if ( pop_to_save[i].size() > 0 )
{
n = pop_to_save[i][0].to_ulong();
const char* buffer = reinterpret_cast<const char*>(&n);
file.write(buffer, pop_to_save[i].size());
}
}
}
因此我需要的是一个可以加载的函数,即:
population genetic_algorithm::load_generation(string filename){
// TODO
}
此致,
马蒂亚斯。
编辑
我自己解决了这个问题(在评论的帮助下) 这是可能面临相同问题的任何人的最终代码:
void genetic_algorithm::save_generation(population pop_to_save, string filename){
std::ofstream file(filename, std::ofstream::binary);
unsigned long n;
for(size_t i = 0; i < pop_to_save.size(); i++ ) {
for (size_t j = 0; j < pop_to_save[i].size(); j++) {
n = pop_to_save[i][j].to_ulong();
file.write(reinterpret_cast<const char*>(&n), sizeof(n));
}
}
std::cout << "Saved population to: " << filename << '\n';
}
population genetic_algorithm::load_generation(string filename){
std::ifstream file(filename, std::ofstream::binary);
population loaded_pop (20, std::vector<bitset<32>> (394,0));
unsigned long n;
for(size_t i = 0; i < 20; i++ ) {
for (size_t j = 0; j < 394; j++) {
file.read( reinterpret_cast<char*>(&n), sizeof(n) );
loaded_pop[i][j] = n;
}
}
std::cout << "Loaded population from: " << filename << '\n';
return loaded_pop;
}
我检查了你的方法 genetic_algorithm::save_generation()
,这是我发现的:
bitset<32>
以压缩形式存储 32 位(可能是unsigned int
和 32 位或类似的东西)。vector<bitset<32> >
存储此类位集的动态数组。vector<vector<bitset<32> > >
存储这样的位集动态数组的动态数组。
到目前为止,还不错。在您的方法 genetic_algorithm::save_generation()
中,您循环遍历外部向量的所有元素以转储每个内部向量的内容(如果不为空)。
file.write(buffer, pop_to_save[i].size());
可能不是您想要的。第二个参数。 of std::ostream::write()
是字符数。你传递了 resp 的 size()
。 returns 元素数量(但不是字节大小)的内部向量。但是元素大小 (bitset<32>
) 可能比一个字符大。更好的方法(虽然不是最好的)是使用 file.write(buffer, 4 * pop_to_save[i].size());
。 (sizeof (char)
:1,sizeof bitset<32>
:希望是 4,但我会检查一下。)
因此,使用 file.write(buffer, pop_to_save[i].size() * sizeof pop_to_save[i][0]);
更安全。这更好,但仍然不完美。如果你想在多个平台上使用你的应用程序,这可能会失败,因为文件格式现在变得依赖于平台。 (取决于sizeof pop_to_save[i][0]
。)
因此,最好的方法是也为内部向量创建一个嵌套循环,并使用一种平台独立大小(例如 std::uint32_t
)单独存储它们的元素。
然而,我真正关心的是设计问题:
如果您存储动态数组的动态数组(其中每个内部数组可能是任意大小),那么您还必须存储这些内部数组的元素数量。这就是我想念你的方法 genetic_algorithm::save_generation()
.
可能是,您的加载问题是由于您必须为要加载的位保留或调整内部向量的大小但您不知道大小。我的回答是:你不可能知道。此信息丢失(必须以某种方式提供,例如由文件本身提供)。