2012-06-08 2 views
1

현재 erlang을 배우려고하고 있는데, 내가하려고하는 것은 비트 배열이나 int에 저장된 배열의 특정 인덱스에 연산을 수행하는 것입니다. 한 위치에 0이 있으면 해당 위치에있는 배열의 인덱스는 사용되지 않습니다.Erlang 비트 인덱싱

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이 비트 문자열 주위에 특별한 문법을 ​​가지고 있다는 것을 알고있다. (< < >>) 그래서 비트 배열에 효율적인 방법으로 인덱스를 얻는다.

답변

1

대부분의 경우 Erlang은 목록과 재귀를 사용하므로 각 비트를 반복적으로 인덱싱하려고 시도하는 것이 아니라 개별적으로 각 비트를 통과하는 것이 관례입니다.

The documentation on how to work with bitstrings is here. 숫자 21에서 비트 문자열을 만들려면 <<21>>을 쓸 수 있습니다. 바이너리의 멤버의 디폴트 타입은 integer이며, 정수의 디폴트 사이즈는 8이므로, 00010101과 같은 비트 스트링을 생성 할 것이다. 값의 마지막 N 바이트를 구체적으로 가져 오려면 <<Value:N>>입니다. 21의 마지막 5 비트를 얻기 위해 을 산출 할 <<21:5>>이라고 말할 수 있습니다. 이 목록의 비트 또는 항목이 부족할 때

-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이 나머지 비트 문자열 값으로 설정됩니다. Bit 값에 따라 현재 항목을 목록에 추가할지 여부를 결정합니다.

예 호출 아래 :

> 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] 
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). 

나는 너무 지능형리스트 아주 좋은 것입니다 확신합니다. 독자의 연습 문제로 떠남 :