汉明距离与Powershell的比较

时间:2018-11-19 21:50:08

标签: powershell

我如何将8位与另外8位进行比较以得到这样的结果:

first Nr     1 0 0 0 1 1 0 1
second Nr    1 0 1 0 1 0 0 0
Result       r r f r r f r f

r = right 
f = false

谢谢

2 个答案:

答案 0 :(得分:2)

您可以使用bitwise comparison operators

例如

[byte]$a = 9       #00001001
[byte]$b = 12      #00001100

-bnot ($a -bxor $b) #11111010

$a -band $b        #00001000
$a -bor $b         #00001101

对于您的情况,您正在查看-bxor功能,只取结果的负数(-bnot)。


如果需要自己查看标志,则可以使用以下方法:

function Format-BooleanString {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [byte]$ByteToDisplay 
    )
    Process {
        [string]$result = ''
        for ([int]$i = 7; $i -ge 0; $i--) {
            [int]$x = [Math]::Pow(2, $i)
            if ($ByteToDisplay -band $x) {
                $result += '1'
            } else {
                $result += '0'
            }
        }
        $result
    }
}
function Convert-BooleanStringToByte {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$ByteAsString
    )
    Process {
        if ($ByteAsString -notmatch '^[01]{8}$') {
            throw 'Input string must be 8 chars, consisting of only 0s and/or 1s'
        }
        [int]$result = 0
        for ([int]$i = 0; $i -lt 8; $i++) {
            if ($ByteAsString[$i] -eq '1') {
                $result += [Math]::Pow(2, 7-$i)
            }
        }
        [byte]$result            
    }

}

Format-BooleanString -ByteToDisplay 9
Convert-BooleanStringToByte -ByteAsString '00100010'

答案 1 :(得分:1)

带注释的解决方案:

$firstNrBin  = '1 0 0 0 1 1 0 1'
$secondNrBin = '1 0 1 0 1 0 0 0'

# Convert the binary number strings to [byte]s (unsigned 8-bit values).
$firstNr = [Convert]::ToByte($firstNrBin -replace ' ', 2)   # 141 == 0x8d
$secondNr = [Convert]::ToByte($secondNrBin -replace ' ', 2) # 168 == 0xa8

# Perform bitwise XOR logic and negate the result to get a bit field
# that reflects the bits where the input numbers match.
# Note the need use of -band 0xff to limit the result to 8 bits - see
# explanation below.
# -> 218 == 0xda = 11011010
$bitsInCommon = [byte] (-bnot ($firstNr -bxor $secondNr) -band 0xff)

# Convert the bit field back into a binary representation, 0-padded to 8 chars.
# -> '11011010'
$bitsInComminBin = [Convert]::ToString($bitsInCommon, 2).PadLeft(8, '0')

# Produce the desired output format with string manipulation
$result = ([char[]] $bitsInComminBin -replace '1', 'r' -replace '0', 'f') -join ' '

# Output the result
[ordered] @{
  'first Nr' = $firstNrBin
  'second Nr' = $secondNrBin
  'Result' = $result
}

以上结果:

Name                           Value
----                           -----
first Nr                       1 0 0 0 1 1 0 1
second Nr                      1 0 1 0 1 0 0 0
Result                         r r f r r f r f

请注意, PowerShell的按位运算符输出[int]-System.Int32作为最小的数据类型,即 signed 数字

因此,您必须使用-band运算符显式屏蔽掉多余的位,因为直接强制转换为 unsigned 类型无效。

在眼前的情况下:

$firstNr -bxor $secondNr # 141 -bxor 168

产生37作为[int]值,即以下32位:

00000000000000000000000000100101

对此-bnot应用[int]会产生按位补码:

11111111111111111111111111011010

作为[int],这是一个数字,因为高位已设置:-38

您不能将其直接转换回无符号类型,例如[byte]仅获得最低的8位,但是可以将-band与位掩码0xff一起使用以将所有位归零超出了前8个-但请注意,此时的结果仍然是[int]

-bnot -38 -band 0xff

产生以下位:

00000000000000000000000000100101

作为[int],这是37,您可以放心地将其投射回[byte]