Golang算法模板-标准输入输出处理

95 阅读5分钟

标准输入处理

go接受输入的方式有4种,fmt.Scan,fmt.Scanf,fmt.Scanln,bufio.NewScanner

总结:

  • 如果输入全是空格,没有其他像逗号这种的格式

    • 如果每一行可确定输入的数量或数量很少,用fmt.Scan(fmt.Scan参数需要指定给哪些变量)
    • 如果每行数量很多,无法确定数量,用bufio.NewScanner,(bufio.NewScanner从标准输入中逐行读取)
  • 如果输入有格式,比如像逗号这种,

    • 如果数量较少,用fmt.Scanf,但是要注意多行输入需要在格式串最后加换行符fmt.Scanf("..\n", ..)
    • 数量较多,用fmt.Scanln,(fmt.Scanln每一行只能读到空格就被截断了)

fmt.Scan

使用场景:读取一段空格分隔字符串或多个数值类型的输入

  • 示例,输入格式,仅输入一行,包括两个浮点数a, b
1.1 2.2
func main() {
    var a, b float64
    _, err := fmt.Scan(&a, &b)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%f, %f", a, b)
}

fmt.Scanf

使用场景:适用于需要按特定格式读取和处理输入数据的场景,例如读取时间、日期、金额等

  • 示例,输入三个数字,中间用逗号隔开
func main() {
    var a, b, c int
    fmt.Scanf("%d,%d,%d", &a, &b, &c)
    fmt.Println(a, b, c)
}

fmt.Scanln

使用场景:从标准输入中读取一行

func main() {
    var input string
    fmt.Scanln(&input)
    strArray := strings.Split(input, ",")
    intArray := make([]int, len(strArray))
    for i, v := range strArray {
        var err error
        intArray[i], err = strconv.Atoi(strings.TrimSpace(v))
        if err != nil {
            fmt.Println(err)
        }
    }
    fmt.Println(intArray)
}

bufio.NewScanner

使用场景:从标准输入中逐行读取。直到遇到文件尾或输入流关闭

  • 示例1,输入很多个数字,中间用逗号隔开

思路是当成字符串读取,然后逗号分隔每个元素,获得一个字符串数组,然后用Atoi函数将字符串转成整数,这里只需要读入一行

func main() {
    var input string
    scanner := bufio.NewScanner(os.Stdin)
    if scanner.Scan() {
        input = scanner.Text()
    } else {
        fmt.Println("error")
    }
    strArray := strings.Split(input, ",")
    intArray := make([]int, len(strArray))
    for i, v := range strArray {
        var err error
        intArray[i], err = strconv.Atoi(strings.TrimSpace(v))
        if err != nil {
            fmt.Println(err)
        }
    }
    fmt.Println(intArray)
}
  • 示例2,输入多行字符串
hello
hello world~
hello hello world!
func main() {
    var strArray []string
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        input := scanner.Text()
        if input == "" {
            break
        }
        strArray = append(strArray, input)
    }
    if err := scanner.Err(); err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(strArray)
}

读写文件

os.Open

func main() {
    file, err := os.Open("text.txt")
    if err != nil {
        fmt.Println(err)
    }
    defer file.Close()
​
    buffer := make([]byte, 1024)
    for {
        bytesReadLen, err := file.Read(buffer)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(bytesReadLen, buffer[:bytesReadLen], string(buffer))
        if bytesReadLen < 1024 {
            break
        }
    }
}

牛客网输入输出练习

https://ac.nowcoder.com/acm/contest/5657#question

A+B(1)

输入描述:输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。

输出描述:输出a+b的结果

fmt.Scanfmt.Scanln可以自动读入换行

func main() {
    var a, b int
    for {
        n, _ := fmt.Scan(&a, &b)    //也可以用fmt.Scanln(&a, &b),或者fmt.Scanf("%d%d\n", &a, &b)
        if n == 0 {
            break
        } else {
            fmt.Printf("%d\n", a+b)
        }
    }
}   

A+B(2)

输入描述:输入第一行包括一个数据组数t(1 <= t <= 100)

接下来每行包括两个正整数a,b(1 <= a, b <= 1000)

输出描述:输出a+b的结果

func main() {
    var n, a, b int
    fmt.Scan(&n)
    for i := 0; i < n; i++ {
        fmt.Scan(&a, &b)
        fmt.Printf("%d\n", a+b)
    }
}

A+B(3)

输入描述:输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入

输出描述:输出a+b的结果

func main() {
    var a, b int
    for {
        fmt.Scan(&a, &b)
        if a == 0 && b == 0 {
            break
        } else {
            fmt.Printf("%d\n", a+b)
        }
    }
}   

A+B(4)

输入描述: 输入数据包括多组。 每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。 接下来n个正整数,即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

func main() {
    var n int
    for {
        fmt.Scan(&n)
        if n == 0 {
            break
        } else {
            intArray := make([]int, n)
            var sum int = 0
            for i := 0; i < n; i++ {
                fmt.Scan(&intArray[i])
                sum += intArray[i]
            }
            fmt.Printf("%d\n", sum)
        }
    }
}

A+B(5)

输入描述: 输入的第一行包括一个正整数t(1 <= t <= 100), 表示数据组数。 接下来t行, 每行一组数据。 每行的第一个整数为整数的个数n(1 <= n <= 100)。 接下来n个正整数, 即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

func main() {
    var t, n int
    fmt.Scan(&t)
    for i := 0; i < t; i++ {
        fmt.Scan(&n)
        intArray := make([]int, n)
        var sum int = 0
        for j := 0; j < n; j++ {
            fmt.Scan(&intArray[i])
            sum += intArray[i]
        }
        fmt.Printf("%d\n", sum)
    }
}   

A+B(6)

输入描述: 输入数据有多组, 每行表示一组输入数据。 每行的第一个整数为整数的个数n(1 <= n <= 100)。 接下来n个正整数, 即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

func main() {
    var n int
    for {
        r, _ := fmt.Scan(&n)
        if r == 0 { //没有输入
            break
        } else {
            intArray := make([]int, n)
            sum := 0
            for i := 0; i < n; i++ {
                fmt.Scan(&intArray[i])
                sum += intArray[i]
            }
            fmt.Printf("%d\n", sum)
        }
    }
}

A+B(7)

输入描述: 输入数据有多组, 每行表示一组输入数据。

每行不定有n个整数,空格隔开。(1 <= n <= 100)。 输出描述: 每组数据输出求和的结果

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        input := scanner.Text()
        if input == "" {
            break
        }
        inputStr := strings.Split(input, " ")
        sum := 0
        for _, curStr := range inputStr {
            val, _ := strconv.Atoi(curStr)
            sum += val
        }
        fmt.Printf("%d\n", sum)
    }
}

字符串排序(1)

输入描述: 输入有两行,第一行n

第二行是n个字符串,字符串之间用空格隔开 输出描述: 输出一行排序后的字符串,空格隔开,无结尾空格

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    scanner.Scan()
    strs := strings.Split(scanner.Text(), " ")
    sort.Strings(strs)
    fmt.Println(strings.Join(strs, " "))
}

字符串排序(2)

输入描述: 多个测试用例,每个测试用例一行。

每行通过空格隔开,有n个字符,n<100 输出描述: 对于每组测试用例,输出一行排序过的字符串,每个字符串通过空格隔开

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        strs := strings.Split(scanner.Text(), " ")
        sort.Strings(strs)
        fmt.Println(strings.Join(strs, " "))
    }
}

字符串排序(3)

输入描述: 多个测试用例,每个测试用例一行。 每行通过,隔开,有n个字符,n<100 输出描述: 对于每组用例输出一行排序后的字符串,用','隔开,无结尾空格

  • bufio.NewScanner
func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        strs := strings.Split(scanner.Text(), ",")
        sort.Strings(strs)
        fmt.Println(strings.Join(strs, ","))
    }
}
  • fmt.Scanln
func main() {
    for {
        var line string
        r, _ := fmt.Scanln(&line)
        if r == 0 {
            break
        }
        strs := strings.Split(line, ",")
        sort.Strings(strs)
        fmt.Println(strings.Join(strs, ","))
    }
}