Read line of numbers in Go

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

Read line of numbers in Go

问题

我有以下输入,第一行是N-数字的数量,第二行是N个数字,用空格分隔:

5
2 1 0 3 4

在Python中,我可以在不指定数量(N)的情况下读取数字:

_ = input()
numbers = list(map(int, input().split()))

在Go语言中,我该如何做到这一点?还是我必须确切地知道有多少个数字?

英文:

I have the following input, where on the first line is N - count of numbers, and on the second line N numbers, separated by space:

5
2 1 0 3 4

In Python I can read numbers without specifying its count (N):

_ = input()
numbers = list(map(int, input().split()))

How can I do the same in Go? Or I have to know exactly how many numbers are?

答案1

得分: 1

你可以使用bufio逐行迭代文件(使用bufio)[https://golangdocs.com/golang-read-file-line-by-line],并且strings模块可以将字符串拆分为切片([https://yourbasic.org/golang/split-string-into-slice/])。所以我们可以得到以下代码:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	readFile, err := os.Open("data.txt")
	defer readFile.Close()

	if err != nil {
		fmt.Println(err)
	}
	fileScanner := bufio.NewScanner(readFile)

	fileScanner.Split(bufio.ScanLines)

	for fileScanner.Scan() {

		// 从文件中获取下一行
		line := fileScanner.Text()

		// 将其拆分为以空格分隔的标记列表
		chars := strings.Split(line, " ")

		// 创建一个与chars切片长度相同的整数切片
		ints := make([]int, len(chars))

		for i, s := range chars {
			// 将字符串转换为整数
			val, err := strconv.Atoi(s)
			if err != nil {
				panic(err)
			}

			// 更新ints切片中相应位置的值
			ints[i] = val
		}

		fmt.Printf("%v\n", ints)
	}
}

对于给定的示例数据,它将输出:

[5]
[2 1 0 3 4]
英文:

You can iterate through a file line-by-line using bufio, and the strings module can split a string into a slice. So that gets us something like:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	readFile, err := os.Open("data.txt")
	defer readFile.Close()

	if err != nil {
		fmt.Println(err)
	}
	fileScanner := bufio.NewScanner(readFile)

	fileScanner.Split(bufio.ScanLines)

	for fileScanner.Scan() {

		// get next line from the file
		line := fileScanner.Text()

		// split it into a list of space-delimited tokens
		chars := strings.Split(line, " ")

		// create an slice of ints the same length as
		// the chars slice
		ints := make([]int, len(chars))

		for i, s := range chars {
			// convert string to int
			val, err := strconv.Atoi(s)
			if err != nil {
				panic(err)
			}

			// update the corresponding position in the
			// ints slice
			ints[i] = val
		}

		fmt.Printf("%v\n", ints)
	}
}

Which given your sample data will output:

[5]
[2 1 0 3 4]

答案2

得分: 1

由于您知道分隔符并且只有两行,这也是一种更紧凑的解决方案:

package main

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
)

func main() {

	parts, err := readRaw("data.txt")
	if err != nil {
		panic(err)
	}

	n, nums, err := toNumbers(parts)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%d: %v\n", n, nums)
}

// readRaw读取输入文件并将其中的数字作为字符串切片返回
func readRaw(fn string) ([]string, error) {
	b, err := os.ReadFile(fn)
	if err != nil {
		return nil, err
	}
	return regexp.MustCompile(`\s`).Split(strings.TrimSpace(string(b)), -1), nil
}

// toNumbers处理输入字符串,将数据作为整数切片返回
func toNumbers(parts []string) (int, []int, error) {
	n, err := strconv.Atoi(parts[0])
	if err != nil {
		return 0, nil, err
	}
	nums := make([]int, 0)
	for _, p := range parts[1:] {
		num, err := strconv.Atoi(p)
		if err != nil {
			return n, nums, err
		}
		nums = append(nums, num)
	}

	return n, nums, nil
}

输出结果为:

5: [2 1 0 3 4]
英文:

Since you know the delimiter and you only have 2 lines, this is also a more compact solution:

package main

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
)

func main() {

	parts, err := readRaw("data.txt")
	if err != nil {
		panic(err)
	}

	n, nums, err := toNumbers(parts)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%d: %v\n", n, nums)
}

// readRaw reads the file in input and returns the numbers inside as a slice of strings
func readRaw(fn string) ([]string, error) {
	b, err := os.ReadFile(fn)
	if err != nil {
		return nil, err
	}
	return regexp.MustCompile(`\s`).Split(strings.TrimSpace(string(b)), -1), nil
}

// toNumbers plays with the input string to return the data as a slice of int
func toNumbers(parts []string) (int, []int, error) {
	n, err := strconv.Atoi(parts[0])
	if err != nil {
		return 0, nil, err
	}
	nums := make([]int, 0)
	for _, p := range parts[1:] {
		num, err := strconv.Atoi(p)
		if err != nil {
			return n, nums, err
		}
		nums = append(nums, num)
	}

	return n, nums, nil
}

The output out be:

5: [2 1 0 3 4]

huangapple
  • 本文由 发表于 2022年8月27日 03:44:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/73505838.html
匿名

发表评论

匿名网友

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

确定