将 '0 1 1 0 1' 格式的字符串快速转换为位集
Quickly converting a string in the format of '0 1 1 0 1' into a bitset
如何快速将由空格分隔的一和零字符串转换为bitset
?
存在一个构造函数,用于从不以空格分隔的字符串初始化bitset
,一个构造函数用于将bitset
初始化为所有零或一,另一个用于从整数初始化。在我的脑海中,我可以想到三种方法:
- 从字符串中删除空格并将其传递给构造函数
- 将二进制文件转换为整数并将其传递给构造函数
- 将所有值初始化为零,并根据 for 循环中的字符串更改每个位的值
每个字符串正好有 24 位,不多也不少。
编辑:这是我用来测试性能的代码,这是方法一和方法二的代码。在我的机器上,方法 1 需要 3 毫秒,方法 3 需要 14 毫秒。
编辑2:我使用-O3 -o -g --std=c++11
是我的编译器设置。我用了gcc和clang。
通过相应地设置每个位,将(不改变输入字符串(转换为无符号整数:
#include <bitset>
constexpr unsigned long long
extract_bits(const char* ptr, unsigned long long accumulator) {
return (*ptr == 0)
? accumulator
: extract_bits(ptr + 1, (*ptr == '1')
? accumulator << 1u | 1u
: (*ptr == '0')
? accumulator << 1
: accumulator);
}
template <unsigned N>
constexpr std::bitset<N>
to_bitset(const char* ptr) {
return std::bitset<N>(extract_bits(ptr, 0));
}
#include <iostream>
int main()
{
constexpr auto b = to_bitset<24>("0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0");
std::cout << b << 'n';
return 0;
}
注意:转换会悄悄地忽略"0"和"1"以外的任何字符(像"01-01"这样的字符串也是有效的(。
获取上述转换的计时并使用以下方法从字符串中删除空格:
#include <algorithm>
#include <cctype>
#include <cstring>
#include <chrono>
#include <iostream>
#include <random>
using namespace std::chrono;
void print_duration(const char* what, const system_clock::time_point& start, const system_clock::time_point& stop) {
auto duration = duration_cast<microseconds>(stop - start);
std::cout << what << ": " << duration.count() << std::endl;
}
volatile unsigned long long result;
int main()
{
std::string str = "0 0 1 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 0";
std::vector<std::string> strings(1000, str);
std::random_device random_device;
std::mt19937 random_generator(random_device());
for(auto& str : strings) {
std::shuffle(str.begin(), str.end(), random_generator);
}
// Non mutating to_bitset
{
auto start = system_clock::now();
for(const auto& str : strings) {
auto b = to_bitset<24>(str.c_str());
result = b.to_ullong();
}
auto stop = system_clock::now();
print_duration("to_bitset", start, stop);
}
// Erasing spaces
{
auto start = system_clock::now();
for(auto& str : strings) {
str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());
auto b = std::bitset<24>(str);
result = b.to_ullong();
}
auto stop = system_clock::now();
print_duration("str.erase", start, stop);
}
return 0;
}
g++ 4.8.4 与 g++ -std=c++11 -O3 显示:
to_bitset
比erasing spaces from a string/constructing a bitset
快约3倍。
相关文章:
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 检查不带转换的扫描格式
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- 将CHW格式的浮点向量转换为cv::Mat
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 如何在C++中将 chrono::秒转换为 HH:MM:SS 格式的字符串?
- 以C++格式将字符串转换为数字
- 将 BGR 图像转换为 jpeg 格式的 base64 字符串
- 将'\x00\x00\x00'格式的字符串转换为无符号字符数组
- 如何在C++中将"%Y%m%d"格式字符串转换为time_t变量?
- 如何将小端格式的QByteArray转换为无符号长整型
- 将毫秒转换为给定格式的持续时间
- 如何将 2d 数组转换为 svg 或 png 格式的数独图像?
- 时间转换为 24 小时格式 cpp
- 如何将字符串(2019年10月3日星期四18:45:10)转换为cpp中的time_t格式?
- 输出使用 cout 转换为 ASCII 的文本时输出格式不正确,C++
- 如何在OpenCV中将4维矩阵转换为NHWC格式
- C++ 将字符串数据包转换为 iphdr语言 - 字符串数据包的格式应该是什么?
- 1 字节整数不转换 I/O 格式
- time_t转换格式问题