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

如何翻转Erlang位串中的单个特定位?

如何在Erlang中翻转位串的单个特定位?

看起来你已经为位串操作写了不错的基础模块啦!要实现翻转单个特定位的功能其实很简单——核心就是把目标位的0和1互相取反。我来帮你完善这个模块:

首先先确认一下你现有的bitutils模块代码:

-module (bitutils).
-export ([get_bits/1, get_bit/2, set_bit/2]).

get_bits(B) -> 
    << <<X>> || <<X:1>> <= B >>.

get_bit(Bin, N) -> 
    << _:N/bitstring, Bit:1, _/bitstring >> = Bin, 
    Bit.

set_bit(Bin, N) -> 
    << A:N, _:1, B/bitstring >> = Bin, 
    << A:N, 1:1, B >>.

还有你提供的REPL测试示例:

Eshell V9.3 (按^G终止)
1> c(bitutils).
{ok,bitutils}
2> B = <<0:3>>.
<<0:3>>

实现flip_bit/2函数

翻转位的逻辑很直接:先定位到目标位,取反它的值,再重新构造位串。这里有几种实现思路:

1. 基于你现有函数的基础实现

可以复用你已经写好的get_bit/2来获取当前位的值,取反后再构造新的位串:

flip_bit(Bin, N) ->
    CurrentBit = get_bit(Bin, N),
    NewBit = 1 - CurrentBit, % 0变1,1变0
    << Pre:N/bitstring, _:1, Post/bitstring >> = Bin,
    << Pre/bitstring, NewBit:1, Post/bitstring >>.

2. 更高效的直接模式匹配实现

不用调用额外函数,直接通过模式匹配定位目标位并取反:

flip_bit(Bin, N) ->
    << Pre:N/bitstring, Bit:1, Post/bitstring >> = Bin,
    << Pre/bitstring, (1 - Bit):1, Post/bitstring >>.

3. 增加边界检查的健壮版

上面的实现如果传入无效的索引(比如超出位串长度)会抛出模糊的模式匹配异常,我们可以添加守卫子句来做参数校验,抛出更明确的错误:

flip_bit(Bin, N) when is_bitstring(Bin), N >= 0, N < bit_size(Bin) ->
    << Pre:N/bitstring, Bit:1, Post/bitstring >> = Bin,
    << Pre/bitstring, (1 - Bit):1, Post/bitstring >>;
flip_bit(_Bin, N) ->
    error({invalid_bit_index, N}).

更新完整模块

把flip_bit/2添加到导出列表里,最终的模块代码如下:

-module (bitutils).
-export ([get_bits/1, get_bit/2, set_bit/2, flip_bit/2]).

get_bits(B) -> 
    << <<X>> || <<X:1>> <= B >>.

get_bit(Bin, N) when N >= 0, N < bit_size(Bin) ->
    << _:N/bitstring, Bit:1, _/bitstring >> = Bin, 
    Bit;
get_bit(_Bin, N) ->
    error({invalid_bit_index, N}).

set_bit(Bin, N) when N >= 0, N < bit_size(Bin) ->
    << Pre:N/bitstring, _:1, Post/bitstring >> = Bin, 
    << Pre/bitstring, 1:1, Post/bitstring >>;
set_bit(_Bin, N) ->
    error({invalid_bit_index, N}).

flip_bit(Bin, N) when is_bitstring(Bin), N >= 0, N < bit_size(Bin) ->
    << Pre:N/bitstring, Bit:1, Post/bitstring >> = Bin,
    << Pre/bitstring, (1 - Bit):1, Post/bitstring >>;
flip_bit(_Bin, N) ->
    error({invalid_bit_index, N}).

测试示例

在REPL里测试一下翻转功能:

3> B1 = <<1:3>>. % 位串是 111
<<1:3>>
4> bitutils:flip_bit(B1, 0). % 翻转第0位,变成110
<<6:3>>
5> B2 = <<0:1,1:1,0:1>>. % 位串是010
<<2:3>>
6> bitutils:flip_bit(B2, 1). % 翻转第1位,变成000
<<0:3>>
7> bitutils:flip_bit(B2, 3). % 传入无效索引,抛出明确错误
** exception error: {invalid_bit_index,3}
     in function  bitutils:flip_bit/2 (bitutils.erl, line 18)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:55:11