如何将数字转换为字符串,格式为1 = A1,2 = A2,... 9 = B1,... 64 = H8在Golang?

时间:2016-08-11 09:18:12

标签: string go char int chess

此代码正在提供A1..A9, B0..B9, C0..C9, ...

但我只想要A1..A8, B1..B8, C1..C8, D1..D8, E1..E8, F1..F8, G1..G8, H1..H8(1-64)。

package main

import (
    "fmt"
)

func ToString(n int8) string {

    return string((n/10)+65) + string(((n%10)+49)-1)

}

func main() {
    var i int8
    for i = 1; i < 11; i++ {
        fmt.Println(ToString(i))
    }
}

2 个答案:

答案 0 :(得分:3)

首先,你要用错误的数字除以。如果您希望数字最多为8,则需要除以8。

其次,您不需要在第二个字符串中减去一个,但您需要减少n

func ToString(n int8) string {
    n--
    return string((n/8)+65) + string((n%8)+49)
}

func main() {
    var i int8
    for i = 1; i <= 64; i++ {
        fmt.Println(ToString(i))
    }
}

https://play.golang.org/p/BdAce3C5JL

答案 1 :(得分:3)

让我们看看不同的方法和性能改进。

所有解决方案和基准测试代码均可在Go Playground上找到。 Playground上的代码是测试文件,而不是可执行文件。您必须将其保存到名为XX_test.go的文件中,并使用go test -bench .运行它。

字符串连接

Ainar-G的回答很酷(+1):

func ToStringConcat(n byte) string {
    n--
    return string((n/8)+65) + string((n%8)+49)
}

字节切片

但请注意,之前的解决方案会连接2个string值,这些值很高,而且价值很高。特别是如果我们想多次调用ToString()

有人可能会认为,如果我们尝试转换包含2个代码的单个整数(第一个向左移动8位),我们可以省去string连接,但这不会“将整数转换为string会产生string值,其中包含runestring(包含整数的UTF-8表示的[]byte)。

但是我们可能会使用string来表示2个值(字母代码和数字代码),然后我们只需convert这个单个切片值func ToStringSlice(n byte) string { n-- return string([]byte{(n / 8) + 65, (n % 8) + 49}) }

string

字符串常量和切片

Go中的

string值为slicable,这会产生新的string(新的string标头)。所以我们可以使用所有值的const values = " A1A2A3A4A5A6A7A8B1B2B3B4B5B6B7B8C1C2C3C4C5C6C7C8D1D2D3D4D5D6D7D8E1E2E3E4E5E6E7E8F1F2F3F4F5F6F7F8G1G2G3G4G5G6G7G8H1H2H3H4H5H6H7H8" func ToStringConst(n byte) string { n *= 2 return values[n : n+2] } 常量,并进行简单的切片以获得我们需要的部分:

string

词典

即使切片string会导致共享底层数组的子字符串,它也需要创建一个新的map标题。

由于我们没有很多可能的值,因此最好(最快)的解决方案是准备所有可能的值,然后进行简单的查找。由于输入是一个数字,我们甚至不需要[]string,我们可以使用简单的var dict = []string{"", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "G1", "G2", "G3", "G4", "G5", "G6", "G7", "G8", "H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8", } func ToStringDict(n byte) string { return dict[n] } 切片:

func BenchmarkConcat(b *testing.B) {
    for i := 0; i < b.N; i++ { ToStringConcat(1) }
}

func BenchmarkSlice(b *testing.B) {
    for i := 0; i < b.N; i++ { ToStringSlice(1) }
}

func BenchmarkConst(b *testing.B) {
    for i := 0; i < b.N; i++ { ToStringConst(1) }
}

func BenchmarkDict(b *testing.B) {
    for i := 0; i < b.N; i++ { ToStringDict(1) }
}

速度分析(基准)

让我们解决上述解决方案的基准速度:

BenchmarkConcat-4       20000000               106 ns/op
BenchmarkSlice-4        100000000               17.0 ns/op
BenchmarkConst-4        2000000000               1.34 ns/op
BenchmarkDict-4         2000000000               1.04 ns/op

结果:

fmt

只需从连接跳转到切片转换,它就会立即快6倍

利用字符串切片,我们再次快12倍

预先构建所有可能的值并进行简单查找,我们进一步获得22%

比较最终到初始:字典查找比原始连接快<100>

使用func ToStringFmt(n byte) string { n-- return fmt.Sprintf("%c%c", (n/8)+65, (n%8)+49) }

为了完整起见,这是使用fmt包的解决方案:

interface{}

但是这个比我们最慢的String连接解决方​​案慢了近2.5倍,因为这必须将参数包装成string值,创建并将它们放入切片(对于vararg),必须解析并分析格式string,使用反射来处理参数,在缓冲区中构建string表示,最终用于生成返回的import os.path, time from datetime import datetime from pytz import timezone import pytz ts = os.path.getmtime(file_path) dt = datetime.fromtimestamp(ts, pytz.utc) timeZone= timezone('supported_timezone') #converting the timestamp in ISOdatetime format dt.astimezone(timeZone).isoformat() 值。很多事情都发生在&#34; general&#34;我们的&#34;特殊&#34;情况下。