如何无中间字符串创建地解析二进制字符串为Vec<u8>?
无中间字符串的二进制字符串转字节数组解析方案
需求回顾
- 解析以
0b开头的二进制字符串 - 忽略字符串中所有下划线
- 从右往左每8位为一组,左侧长度不足8位时补前导零
- 将每组二进制转换为
u8,最终收集为Vec<u8>
优化实现
当然可以做到完全避免中间字符串的创建与拼接,下面是满足所有需求的高效实现:
fn parse_binary(binary: &str) -> Vec<u8> { // 跳过开头的"0b",过滤掉下划线,仅保留有效二进制位的迭代器 let mut bits = binary.chars().skip(2).filter(|&c| c != '_'); // 统计有效二进制位总数,计算需要补充的前导零数量 let total_bits = bits.clone().count(); let pad_bits = (8 - total_bits % 8) % 8; // 若总位数是8的倍数,补零数为0 // 提前分配足够容量,避免动态扩容 let mut bytes = Vec::with_capacity((total_bits + pad_bits) / 8); let mut current_byte = 0u8; let mut bit_count = 0; // 先处理需要补充的前导零 for _ in 0..pad_bits { current_byte <<= 1; bit_count += 1; if bit_count == 8 { bytes.push(current_byte); current_byte = 0; bit_count = 0; } } // 逐位处理有效二进制字符,构建字节 for c in bits { current_byte <<= 1; if c == '1' { current_byte |= 1; } bit_count += 1; if bit_count == 8 { bytes.push(current_byte); current_byte = 0; bit_count = 0; } } bytes } fn main() { let binary = "0b11_1001_0011_1001_00111001"; println!("{:?}", parse_binary(binary)); // 输出 [57, 57, 57] }
实现说明
- 无中间字符串开销:直接遍历原字符串的字符,跳过
0b和下划线,无需将有效位收集为新字符串 - 预分配内存:通过统计有效位数提前计算
Vec<u8>的容量,避免运行时动态扩容的性能损耗 - 逐位构建字节:
- 先补充必要的前导零,按左移逻辑填充到当前字节
- 遍历每个有效二进制位,逐位左移并设置对应值,每凑够8位就将当前字节加入结果数组
- 逻辑对齐需求:补前导零后从左到右分组,等价于原字符串从右往左分组后补零的效果,完全符合需求
内容的提问来源于stack exchange,提问作者Aster
相关产品推荐
相关产品推荐

