Получить часть целых чисел из строкового целого числа в Go? - PullRequest
0 голосов
/ 13 января 2019

Я хочу преобразовать строку, представляющую целое число, в срез, содержащий каждое целое число, составляющее исходную строку.

Ссылка на игровую площадку

Я пытался использовать функцию Atoi() в strconv, она дает "нельзя использовать toCheck [i] (type byte) в качестве строки типа в аргументе для strconv.Atoi" . Я также пробовал преобразование int (), но оно дает мне то, что я считаю значениями ASCII - я знаю, что могу просто вычесть 48, но это выглядит немного странно.

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

Ответы [ 3 ]

0 голосов
/ 13 января 2019

используйте 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

0 голосов
/ 13 января 2019

но это дает мне то, что я считаю значениями ASCII - я знаю, что могу просто вычесть 48, но это выглядит немного странно.

Это не хакерство. У вас есть байт, представляющий цифру ascii, и вы хотите получить его значение в виде целого числа от 0 до 9. Вот как ты это делаешь. Это также, как преобразование строки в целое число работает в целом. Этот метод преобразует каждый отдельный байт в число.

Представление UTF-8 для '0' не изменится в ближайшее время. Конечно, вместо вычитания 48 вы можете вычесть '0'.

Чтобы сделать его более универсальным, возможно, вам также следует вернуть логическое значение, указывающее, можно ли преобразовать байт или нет.

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]

0 голосов
/ 13 января 2019

Например,

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)
        }
    }
}
...