我正在尝试在F#中进行一些反转排列。
https://en.wikipedia.org/wiki/Bit-reversal_permutation
我知道如何在Python中执行此操作:
def bitrev(x, bits):
y = 0
for i in range(bits):
y = (y << 1) | (x & 1)
x >>= 1
return y
,如果给出,则返回以下列表,例如,对于0-15范围内的值,bits = 4:
0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
如何在没有可变值的情况下完成此任务?
答案 0 :(得分:3)
您始终可以采用命令式方法,并从Python直接进行翻译:
let bitrev x bits =
let mutable x = x
let mutable y = 0
for i in 1..bits do
y <- (y <<< 1) ||| (x &&& 1)
x <- x >>> 1
y
您这样运行:
[0..15]
|> List.map (fun n -> bitrev n 4)
|> printfn "%A"
// [0; 8; 4; 12; 2; 10; 6; 14; 1; 9; 5; 13; 3; 11; 7; 15]
具有不变性的功能方式如下:
let bitrev x bits =
let rec bitrevR x bits y =
match bits with
| 0 -> y
| _ ->
bitrevR (x >>> 1) (bits - 1) ((y <<< 1) ||| (x &&& 1))
bitrevR x bits 0
0..15之间的数字的内部表示形式是4位:
binary decimal
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15
颠倒的样子:
binary decimal
0000 = 0 <-> 0000 = 0
0001 = 1 <-> 1000 = 8
0010 = 2 <-> 0100 = 4
0011 = 3 <-> 1100 = 12
0100 = 4 <-> 0010 = 2
0101 = 5 <-> 1010 = 10
0110 = 6 <-> 0110 = 6
0111 = 7 <-> 1110 = 14
1000 = 8 <-> 0001 = 1
1001 = 9 <-> 1001 = 9
1010 = 10 <-> 0101 = 5
1011 = 11 <-> 1101 = 13
1100 = 12 <-> 0011 = 3
1101 = 13 <-> 1011 = 11
1110 = 14 <-> 0111 = 7
1111 = 15 <-> 1111 = 15
答案 1 :(得分:0)
如果您不仅对a(m, k)
和m < 2^k
的各个元素k = 0, 1, 2, ...
感兴趣,而且对{{ 3}}:很容易为它编写一个生成器。
let a030109 =
seq[0] |> Seq.unfold (fun xs ->
let ys = Seq.map ((*) 2) xs
let zs = Seq.map ((+) 1) ys
Some(xs, Seq.append ys zs) )
|> Seq.concat
a030109
|> Seq.skip (pown 2 4 - 1)
|> Seq.take (pown 2 4)
|> Seq.toList
// val it : int list = [0; 8; 4; 12; 2; 10; 6; 14; 1; 9; 5; 13; 3; 11; 7; 15]