在Go语言中,可以对非常长的二进制位字符串进行位运算操作。

huangapple go评论79阅读模式
英文:

golang: bitwise operation on very long binary bit string representation

问题

作为练习,我得到了两个非常大的字符串,其中包含长的二进制表示。这里是一个简短的示例,但可能有超过100位:

示例:

11100
00011

输出为按位或(作为字符串):

11111

我的方法是解析每个字符串的字符,进行按位或操作,并构建一个新的字符串,但对于大型输入来说处理时间太长且不够有效。

然后,ParseInt方法限制为64位长度:

num1, err := strconv.ParseInt("11100", 2, 64)
num2, err := strconv.ParseInt("00011", 2, 64)
res := num1 | num2

如何处理两个字符串二进制表示之间的按位或操作?

英文:

As an exercise, in input I got 2 very big string containing long binary representation here a short one but could have more than 100 bits:

Example

11100
00011

With output in bitwise OR (as string)

11111

My approach was to parse each string characters and make a bitwise OR and build a new string but it is too long to process on big entry and not effective.

Then ParseInt method is restricted to a 64 bit length

num1, err:= strconv.ParseInt("11100", 2, 64)
num2, err:= strconv.ParseInt("00011", 2, 64)
res := num1 | num2

How to deal with a bitwise OR between 2 string binary representation?

答案1

得分: 9

你可以通过字符比较来创建结果的按位或字符串,或者可以使用math/big执行任意大的数值操作。以下是一个示例:

package main

import "fmt"
import "math/big"

func main() {
    num1 := "11100"
    num2 := "00011"

    var bigNum1 big.Int
    var bigNum2 big.Int
    var result big.Int

    if _, ok := bigNum1.SetString(num1, 2); !ok {
        panic("invalid num1")
    }
    if _, ok := bigNum2.SetString(num2, 2); !ok {
        panic("invalid num2")
    }
    result.Or(&bigNum1, &bigNum2)

    for i := result.BitLen() - 1; i >= 0; i-- {
        fmt.Print(result.Bit(i))
    }
    fmt.Println()
}

Go Playground

英文:

You could create the resulting bitwise OR string by doing character comparisons, or you can perform arbitrary large numeric operations using math/big. Here is an example of such an operation:

package main

import "fmt"
import "math/big"

func main() {
	num1 := "11100"
	num2 := "00011"

	var bigNum1 big.Int
	var bigNum2 big.Int
	var result big.Int

	if _, ok := bigNum1.SetString(num1, 2); !ok {
		panic("invalid num1")
	}
	if _, ok := bigNum2.SetString(num2, 2); !ok {
		panic("invalid num2")
	}
	result.Or(&bigNum1, &bigNum2)

	for i := result.BitLen() - 1; i >= 0; i-- {
		fmt.Print(result.Bit(i))
	}
	fmt.Println()
}

Go Playground

答案2

得分: 0

虽然你可以将这些字符串转换为数字来执行位运算,但如果你的目标只是对这两个字符串执行一次位或运算,那么将字符串解析为数字将比仅仅迭代字符串以实现最终结果的方法效率低下。只有在以二进制形式对数字执行大量操作时,这样做才有意义。

下面是在下面的字符串上执行OR操作的示例代码。请注意,此代码假设字符串与问题中的示例长度相同,如果它们的长度不同,您还需要处理这个问题。

package main

import "fmt"

func main() {
    n1 := "1100"
    n2 := "0011"
    
    fmt.Printf("Input: %v | %v\n", n1, n2)
    
    if len(n1) != len(n2) {
        fmt.Println("Only supports strings of the same length")
        return
    }
    
    result := make([]byte, len(n1))
    
    for i := 0; i < len(n1); i++ {
        switch n1[i] {
        case '0':
            switch n2[i] {
            case '0':
                result[i] = '0'
            case '1':
                result[i] = '1'
            }
        case '1':
            switch n2[i] {
            case '0':
                result[i] = '1'
            case '1':
                result[i] = '1'
            }
        }
    }
    
    fmt.Println("Result: ", string(result))
}

你可以在这里运行这段代码:http://play.golang.org/p/L3o6_jYdi1

英文:

While you could convert these to numbers to perform bitwise operations, if your only goal is to perform a single bitwise OR on the two strings, parsing the strings into numbers will be less efficient than simply iterating over the string to achieve your end result. Doing so would only make sense if you were performing lots of operations on the numbers in their binary form.

Example code for performing an OR operation on the strings below. Do note that this code assumes the strings are the same length as the examples in the question are, if they were of different lengths you would need to handle that as well.

package main

import &quot;fmt&quot;

func main() {
	n1 := &quot;1100&quot;
	n2 := &quot;0011&quot;
	
	fmt.Printf(&quot;Input: %v | %v\n&quot;, n1, n2)
	
	if len(n1) != len(n2) {
		fmt.Println(&quot;Only supports strings of the same length&quot;)
		return
	}
	
	result := make([]byte, len(n1))
	
	for i := 0; i &lt; len(n1); i++ {
		switch n1[i] {
		case &#39;0&#39;:
			switch n2[i] {
			case &#39;0&#39;:
				result[i] = &#39;0&#39;
			case &#39;1&#39;:
				result[i] = &#39;1&#39;
			}
		case &#39;1&#39;:
			switch n2[i] {
			case &#39;0&#39;:
				result[i] = &#39;1&#39;
			case &#39;1&#39;:
				result[i] = &#39;1&#39;
			}
		}
	}
	
	fmt.Println(&quot;Result: &quot;, string(result))
}

http://play.golang.org/p/L3o6_jYdi1

答案3

得分: 0

这是一个Go语言的代码片段,它的功能是将两个二进制字符串进行比较,并将它们的对应位进行逻辑运算后输出结果。

package main

import "fmt"

func main() {
    a := "01111100"
    b := "1001000110"

    var longest, len_diff int

    if len(a) > len(b) {
        longest = len(a)
        len_diff = len(a) - len(b)
    } else {
        longest = len(b)
        len_diff = len(b) - len(a)
    }

    temp_slice := make([]byte, longest)

    var a_start, b_start int

    if len(a) > len(b) {
        for i := 0; i < len_diff; i++ {
            temp_slice[i] = a[i]
        }
        a_start = len_diff

    } else {
        for i := 0; i < len_diff; i++ {
            temp_slice[i] = b[i]
        }
        b_start = len_diff
    }

    for i := 0; i < (longest - len_diff); i++ {
        if a[a_start+i] == '1' || b[b_start+i] == '1' {
            temp_slice[len_diff+i] = '1'
        } else {
            temp_slice[len_diff+i] = '0'
        }
    }

    fmt.Println(string(temp_slice))
}

这段代码的作用是比较两个二进制字符串 ab,并将它们的对应位进行逻辑运算后输出结果。你可以在 goplayground 上运行这段代码。

英文:

How about this:

package main

import &quot;fmt&quot;
	
func main(){
	a :=   &quot;01111100&quot;
	b := &quot;1001000110&quot;

	var longest, len_diff int 

	if len(a) &gt; len(b) {
		longest = len(a)
		len_diff = len(a) - len(b)
	} else {
		longest = len(b)
		len_diff = len(b) - len(a)
	}

	temp_slice := make([] byte, longest)

	var a_start, b_start int

	if len(a) &gt; len(b) {
		for i := 0; i &lt; len_diff; i++ {
			temp_slice[i] = a[i]
		}
		a_start = len_diff

	} else {
		for i := 0; i &lt; len_diff; i++ {
			temp_slice[i] = b[i]
		}
		b_start = len_diff
	}

	for i := 0; i &lt; (longest - len_diff); i++ {
		if a[a_start + i] == &#39;1&#39; ||  b[b_start + i] == &#39;1&#39; {
			temp_slice[len_diff + i] = &#39;1&#39;
		} else {
			temp_slice[len_diff + i] = &#39;0&#39;
		}
	}

	fmt.Println(string(temp_slice))
}

goplayground

答案4

得分: 0

尝试使用这个库:https://github.com/aristofanio/bitwiser
你可以像处理bitstring一样解析大型字节数组。示例代码如下:

package main

import (
	"github.com/aristofanio/bitwiser"
)

func main() {
	//
	b0, _ := bitwiser.ParseFromBits("011100")
	b1, _ := bitwiser.ParseFromBits("11010011100")
	//
	println(b0.ToString()) //输出: 0x1c   (数组长度为1字节)
	println(b1.ToString()) //输出: 0x069c (数组长度为2字节)
}
英文:

Alternative: try this library:https://github.com/aristofanio/bitwiser.
you can parse large bytes arrays like bitstring. See:

package main

import (
	&quot;github.com/aristofanio/bitwiser&quot;
)

func main() {
	//
	b0, _ := bitwiser.ParseFromBits(&quot;011100&quot;)
	b1, _ := bitwiser.ParseFromBits(&quot;11010011100&quot;)
	//
	println(b0.ToString()) //output: 0x1c   (len(array) = 1byte)
	println(b1.ToString()) //output: 0x069c (len(array) = 2bytes)
}

huangapple
  • 本文由 发表于 2015年3月12日 05:21:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/28997600.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定