【问题标题】:Getting a slice of integers from a string integer in Go?从 Go 中的字符串整数中获取整数切片?
【发布时间】:2019-06-07 12:09:41
【问题描述】:

我想将表示整数的字符串转换为包含组成初始字符串的每个整数的切片。

Playground link

我尝试在strconv 中使用Atoi() 函数,它给出了“不能在strconv.Atoi 的参数中使用toCheck[i](类型字节)作为类型字符串”。我也尝试过 int() 转换,但它给了我我认为是 ASCII 值的东西 - 我知道我可以减去 48,但这似乎有点 hacky。

package main

import (
    "fmt"
)

func main() {

toCheck := "987654321"

    var toSum []int
    for i := len(toCheck) - 2; i >= 0; i = i-2 {
        toSum = append(toSum, int(toCheck[i]))
    }

    fmt.Println(toSum)

    // expected 2 4 6 8
    // actual 50 52 54 56
}

预期输出:2 4 6 实际:50 52 54 56

【问题讨论】:

    标签: string go int slice


    【解决方案1】:

    但它给了我我认为是 ASCII 值的东西 - 我知道我可以减去 48,但这似乎有点 hacky。

    这不是hacky。您有一个表示 ascii 数字的字节,并且您希望将其值作为 0-9 的整数获取。你就是这样做的。这也是将字符串转换为整数的一般工作方式。您可以使用此方法将每个单独的字节转换为数字。

    “0”的 UTF-8 表示不会很快改变。当然,你可以减去'0',而不是减去48

    为了使其更通用,也许您还应该返回一个布尔值,指示字节是否可以转换。

    func ByteToInt(c byte) (int, bool) {
        if c >= '0' && c <= '9' {
            return int(c - '0'), true
        } else {
            return 0, false
        }
    }
    

    您可以在代码示例中使用它,它会返回您的预期结果:

    package main
    
    import (
        "fmt"
    )
    
    func ByteToInt(c byte) (int, bool) {
        if c >= '0' && c <='9' {
            return int(c - '0'), true
        } else {
            return 0, false
        }
    }
    
    func main() {
    
    toCheck := "987654321"
    
        var toSum []int
        for i := len(toCheck) - 2; i >= 0; i = i-2 {
            var digit, _ = ByteToInt(toCheck[i])
            toSum = append(toSum, digit)
        }
    
        fmt.Println(toSum)
    
    }
    

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

    输出如你所愿:[2 4 6 8]

    【讨论】:

      【解决方案2】:

      例如,

      package main
      
      import (
          "fmt"
      )
      
      func main() {
          toCheck := "987654321"
          fmt.Println(toCheck)
          toSum := make([]int, 0, len(toCheck)/2)
          for i := len(toCheck) - 2; i >= 0; i -= 2 {
              c := toCheck[i]
              if c >= '0' && c <= '9' {
                  toSum = append(toSum, int(c-'0'))
              }
          }
          fmt.Println(len(toSum), cap(toSum), toSum)
      }
      

      游乐场:https://play.golang.org/p/wtIgqEKj-Bk

      输出:

      987654321
      4 4 [2 4 6 8]
      

      这是围棋。代码应该是相当有效的。例如,

      $ go test sum_test.go -bench=. -benchmem
      BenchmarkPeterSO-8         50000000     24.5 ns/op    32 B/op    1 allocs/op
      BenchmarkTom-8             20000000     77.6 ns/op    56 B/op    3 allocs/op
      BenchmarkUser10753492-8    20000000     79.0 ns/op    56 B/op    3 allocs/op
      BenchmarkGrissom-8         20000000    108 ns/op      56 B/op    3 allocs/op
      $
      

      sum_test.go:

      package main
      
      import (
          "strconv"
          "testing"
      )
      
      // https://play.golang.org/p/wtIgqEKj-Bk
      func BenchmarkPeterSO(b *testing.B) {
          toCheck := "987654321"
          for N := 0; N < b.N; N++ {
              toSum := make([]int, 0, len(toCheck)/2)
              for i := len(toCheck) - 2; i >= 0; i -= 2 {
                  c := toCheck[i]
                  if c >= '0' && c <= '9' {
                      toSum = append(toSum, int(c-'0'))
                  }
              }
          }
      }
      
      // https://play.golang.org/p/KgQrbesy5rT
      func BenchmarkTom(b *testing.B) {
          toCheck := "987654321"
          for N := 0; N < b.N; N++ {
              var toSum []int
              for i := len(toCheck) - 2; i >= 0; i = i - 2 {
                  toSum = append(toSum, int(toCheck[i]))
              }
          }
      }
      
      func ByteToInt(c byte) (int, bool) {
          if c >= '0' && c <= '9' {
              return int(c - '0'), true
          } else {
              return 0, false
          }
      }
      
      // https://play.golang.org/p/MRqtgY0ugZY
      func BenchmarkUser10753492(b *testing.B) {
          toCheck := "987654321"
          for N := 0; N < b.N; N++ {
              var toSum []int
              for i := len(toCheck) - 2; i >= 0; i = i - 2 {
                  var digit, _ = ByteToInt(toCheck[i])
                  toSum = append(toSum, digit)
              }
          }
      }
      
      // https://play.golang.org/p/kNbQVn8GJ9R
      func BenchmarkGrissom(b *testing.B) {
          toCheck := "987654321"
          for N := 0; N < b.N; N++ {
              var toSum []int
              for i := len(toCheck) - 2; i >= 0; i = i - 2 {
                  v, _ := strconv.Atoi(string(toCheck[i]))
                  toSum = append(toSum, v)
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        使用strconv包进行转换

          for i := len(toCheck) - 2; i >= 0; i = i-2 {
                v,_ := strconv.Atoi(string(toCheck[i]))
                toSum = append(toSum, v)
            }
        

        strconv.Atoi 是 strconv.ParseInt(s,10,0) 的快捷方式。

        在你的操场上完成 https://play.golang.org/p/kNbQVn8GJ9R

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-24
          相关资源
          最近更新 更多