Go 使用按位运算符而不是 javascript 返回其他总和

我尝试使用 Go 制作在 JS 中制作的函数端口,但我面临着奇怪的问题。函数的目标是将字符串中每个字母的 ascii 代码相加。

一切都很好,直到字符串长度 <= 6 之后 Go 返回其他结果。

来自 JS

function c(e) { // e is string
    var t = 0;
     if (!e) // if e == ""
       return t;
     for (var n = 0; n < e.length; n++) {
            t = (t << 5) - t + e.charCodeAt(n),
            t &= t
     }
     return t
}sd
c("Google") // returns 2138589785
c("Google1") // returns 1871773944

Go 中的端口

package main

import (
    "fmt"
)

func main() {
    fmt.Println(CountChars("Google")) // returns 2138589785
    fmt.Println(CountChars("Google1")) // returns 66296283384
}

func CharCodeAt(s string) int {
    return int([]rune(s)[0])
}

func CountChars(char string) int {
    var sum int = 0
    if char == "" {
        return sum
    }
    for x:=0; x<len(char); x++ {
        charToCode := string(char[x])
        sum = (sum << 5) - sum + CharCodeAt(charToCode)
        sum &= sum
    }
    return sum
}

去游乐场

游戏代码中的 JS 游乐场

回答

Javascript 中的整数是 32 位的,而 Goint是依赖于架构的,可能是 32 位和 64 位。它在 Go Playground 上是 64 位的。并且由于每次迭代向左移动 5,因此在 Javascript 中使用超过 6 个字符肯定会“溢出”(但在 Go 中还没有):7*5=35 > 32 bits.

使用显式 32 位整数 ( int32) 获得与 Javascript 相同的输出:

func CountChars(char string) int32 {
var sum int32 = 0
if char == "" {
return sum
}
for x := 0; x < len(char); x++ {
sum = (sum << 5) - sum + int32(char[x])
sum &= sum
}
return sum
}

这种方式的输出将与 Javascript 的输出相同(在Go Playground上尝试):

2138589785
1871773944

另请注意,Go 将字符串作为其 UTF-8 字节序列存储在内存中,并且索引字符串(如char[x])会为其字节索引,即 UTF-8 序列。这在您的示例中很好,因为所有输入字符都使用单个字节进行编码,但是如果输入包含多字节字符,您将得到不同的结果。

要正确处理所有情况,请for range在字符串上使用 simple : 返回连续的符文,它也是 的别名int32,因此您可以获得所需的代码点。

此外,检查空字符串是不必要的,如果它是空的,则不会执行循环体。另外sum &= sum:这是一个无操作,只需删除它。

简化版:

func CountChars(s string) (sum int32) {
for _, r := range s {
sum = (sum << 5) - sum + r
}
return
}

测试它:

fmt.Println(CountChars("Google ??"))

将输出与 Javascript 相同的输出(在Go Playground上试试这个):

-815903459

这是一个尺寸问题。JS int 是 32 位,Go int 不一定是 32 位。如果您依赖于特定的 int 大小,则应通过替换intwith 的实例来指定它int32

看起来像什么(操场):

package main
import (
"fmt"
)
func main() {
fmt.Println(CountChars("Google"))
fmt.Println(CountChars("Google1"))
}
func CharCodeAt(s string, n int) int32 {
return int32(s[n])
}
func CountChars(char string) int32 {
var sum int32 = 0
if char == "" {
return sum
}
for x:=0; x<len(char); x++ {
sum = (sum << 5) - sum + CharCodeAt(char, x)
sum &= sum
}
return sum
}

以上是Go 使用按位运算符而不是 javascript 返回其他总和的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>