You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无中间字符串创建地解析二进制字符串为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]
}

实现说明

  1. 无中间字符串开销:直接遍历原字符串的字符,跳过0b和下划线,无需将有效位收集为新字符串
  2. 预分配内存:通过统计有效位数提前计算Vec<u8>的容量,避免运行时动态扩容的性能损耗
  3. 逐位构建字节:
    • 先补充必要的前导零,按左移逻辑填充到当前字节
    • 遍历每个有效二进制位,逐位左移并设置对应值,每凑够8位就将当前字节加入结果数组
  4. 逻辑对齐需求:补前导零后从左到右分组,等价于原字符串从右往左分组后补零的效果,完全符合需求

内容的提问来源于stack exchange,提问作者Aster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:43:22