.net F#位反转置换
我想在F#中做一点反转排列 我知道如何在Python中执行此操作:.net F#位反转置换,.net,f#,bit-manipulation,bit,.net,F#,Bit Manipulation,Bit,我想在F#中做一点反转排列 我知道如何在Python中执行此操作: def bitrev(x, bits): y = 0 for i in range(bits): y = (y << 1) | (x & 1) x >>= 1 return y def比特版本(x,比特): y=0 对于范围内的i(位): y=(y>=1 返回y 如果给定0-15范围内的值的位=4,则应返回以下列表: 084122106
def bitrev(x, bits):
y = 0
for i in range(bits):
y = (y << 1) | (x & 1)
x >>= 1
return y
def比特版本(x,比特):
y=0
对于范围内的i(位):
y=(y>=1
返回y
如果给定0-15范围内的值的位=4,则应返回以下列表:
0841221061419513111715
在没有可变值的情况下如何实现这一点?您可以始终按照命令式的方式,直接从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
具有不变性的功能方式如下所示:
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
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
看起来是这样的:
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
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
二进制十进制
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
如果您不仅对单个元素
a(m,k)
感兴趣,其中m<2^k
和k=0,1,2,…
,而且对作为序列中较大块的对合感兴趣:很容易为其编写生成器
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]
所以我实际上做了一个命令式翻译,和你的完全一样,但不管出于什么原因,它只在位=3的情况下对我有效…你能想出一个原因吗?我最终从
1..bits-1
进行了迭代。也感谢函数式翻译!你为我节省了大量的压力-我希望我能多投票。我只是更改了位r从0..3到1..4的范围,关键是要对位进行4次内部移位。我明白了!所以迭代器值不重要,只要你进行4次迭代。