1

私は現在erlangを学ぼうとしています。私がやろうとしているのは、ビット配列またはintに格納されている配列の特定のインデックスに対して操作を実行することです。位置に0がある場合、その位置の配列へのインデックスは使用されません。

したがって、次のことを想像してください。

Example the array is: [1, 3, 5, 42, 23]
My bit array is: 21 = 10101 in binary
so I'm using indicies 1,3,5
so I'm calling a function on [1, 5, 23]

私の関数は次の形式です

my_function(Array, BitArray) ->
    SubArray = get_subarray_from_bitarray(Array, BitArray),
    process_subarray(SubArray).

そして、get_subarray_from_bitarray()のヘルプが必要です。erlangにはビット文字列(<< >>など)の周りに特別な構文があることを知っていますが、インデックスを取得するためにビット配列にインデックスを付ける効率的な方法はありますか?

4

2 に答える 2

1

ほとんどの場合、Erlangはリストと再帰を処理するため、各ビットに繰り返しインデックスを付けるのではなく、各ビットを個別に調べるのが慣用的だと思います。

ビット文字列の操作方法に関するドキュメントはこちらです。 数値21からビット文字列を作成するために、を書くことができます<<21>>。バイナリのメンバーのデフォルトの型は整数であり、整数のデフォルトのサイズは8であるため、のようなビット文字列が生成されます00010101。値の最後のNバイトを具体的に取得する場合は、です<<Value:N>>。21の最後の5ビットを取得するために、<<21:5>>どちらが生成されるかを言うことができます10101

私はあなたが望むことをするために次のモジュールを書きました:

-module(bitmask).
-export([get_subarray_from_bitarray/2]).

get_subarray_from_bitarray(Bitstring, List) ->
  get_subarray_from_bitarray_loop(Bitstring, List, []).

get_subarray_from_bitarray_loop(_Bits, [], Gathered) ->
  io:format("End of list~n", []),
  lists:reverse(Gathered);
get_subarray_from_bitarray_loop(<<>>, _Others, Gathered) ->
  io:format("End of bitstring~n", []),
  lists:reverse(Gathered);
get_subarray_from_bitarray_loop(<<Bit:1, Rest/bitstring>>, [Item | Others], Gathered) ->
  io:format("Bit: ~w ~n", [Bit]),
  case Bit of
    1 -> get_subarray_from_bitarray_loop(Rest, Others, [Item | Gathered]);
    0 -> get_subarray_from_bitarray_loop(Rest, Others, Gathered)
  end.

リスト内のビットまたはアイテムが不足すると、最初の2つの句は最終的なリストを返します。重要なビット構文は、最後の句の先頭にあり<<Bit:1, Rest/bitstring>>ます。これにより、Bitの値がビット文字列の最初のビットの値に設定Restされ、残りのビット文字列に設定されます。ビットの値に応じて、現在のアイテムをリストに追加するかどうかを決定します。

以下の呼び出し例:

> bitmask:get_subarray_from_bitarray(<<21:5>>, [1, 3, 5, 42, 23]).   
Bit: 1 
Bit: 0 
Bit: 1 
Bit: 0 
Bit: 1 
End of list
[1,5,23]
> bitmask:get_subarray_from_bitarray(<<31>>, [1, 3, 5, 42, 23]).  
Bit: 0 
Bit: 0 
Bit: 0 
Bit: 1 
Bit: 1 
End of list
[42,23]
> bitmask:get_subarray_from_bitarray(<<5:3>>, [1, 3, 5, 42, 23]). 
Bit: 1 
Bit: 0 
Bit: 1 
End of bitstring
[1,5]
于 2012-06-09T03:19:51.280 に答える
0

get_subarray_from_bitarray/2関数の可能な実装は次のとおりです。

get_subarray_from_bitarray(Array, BitArray) ->
    gsb(Array, BitArray, []).

gsb(_, 0, R) -> lists:reverse(R);
gsb([A1|A2], B, R) ->
  NextR = if B band 1 /= 0 ->
     [A1|R];
  true ->
     R
  end,
  gsb(A2, B div 2, NextR).

リスト内包表記もあればとてもいいと思います。読者のための演習として残しました:)

于 2012-06-08T22:36:56.650 に答える