![見出し画像](https://assets.st-note.com/production/uploads/images/113134638/rectangle_large_type_2_44196e3f32b13b4a01e2adee0bf6b071.png?width=1200)
Photo by
shiroyukimin
【Go言語】標準入力(2)
paizaラーニング レベルアップ問題集「標準入力メニュー」問題の続きです。
組になったデータの入力
入力が以下のような形式で与えられる問題例です。
整数の組
// N: 整数
// a_k, b_k: 整数
N
a_1 b_1
...
a_N b_N
文字列と整数の組
// N: 整数
// s_k: 文字列
// a_k: 整数
N
s_1 a_1
...
s_N a_N
整数の組の場合、N行2列の二次元配列・スライスで処理する手もありますが、データ型の異なる組の場合、後で型変換の処理が必要になり面倒です。
ここでは一次元配列・スライスをふた組使う手法を取ります。
以下のコードは文字列と整数の組のデータ(FINAL問題)の場合です。C言語ライクな書き方になります。
package main
import "fmt"
func main(){
var n int
fmt.Scan(&n)
s := make([]string, n)
a := make([]int, n)
for i:=0; i<n; i++ {
fmt.Scanf("%s %d", &s[i], &a[i])
}
for j:=0; j<n; j++ {
fmt.Printf("%s %d\n", s[j], a[j])
}
}
N行M列のデータの入力
N行M列の整数の入力
ステップごとにNとMの両方が定数、片方が定数、両方とも変数と変化していきますが、以下は両方とも変数である問題の解答例です。
入力部と出力部は様々な問題に流用できそうなので、関数にすると良いと考えます。
package main
import "fmt"
// 標準入力から整数値を受け取り、n行m列のスライスに入れる
func GenerateArray(n, m int) [][]int {
result := make([][]int, n)
for k := 0; k < n; k++ {
result[k] = make([]int, m)
}
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
fmt.Scan(&result[i][j])
}
}
return result
}
// 二次元スライスを半角スペース区切りで標準出力に表示する
func ShowArray(arr [][]int) {
n := len(arr)
m := len(arr[0])
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
fmt.Print(arr[i][j])
if j != m-1 {
fmt.Print(" ")
}
}
fmt.Println()
}
}
func main() {
var n, m int
fmt.Scan(&n)
fmt.Scan(&m)
arr := GenerateArray(n, m)
ShowArray(arr)
}
[FINAL問題]行ごとに要素数の異なる整数列の入力
要素数が不規則なデータの入力・出力のコードは若干面倒くさいです。
入力は、Pythonの場合、list(map(int, input().split())) の1文で1行のデータを受け取れます。Go言語でも strings.Split() メソッドがあるのですが、ライブラリのインポートが必要であり、Javaのようにスキャナーオブジェクトの宣言も必要です。
ここでは地道にfmt.Scan()を使ってスライスの要素に格納する手法を取ります。
出力部も、自作(AI作)のjoinメソッドを流用します。
package main
import (
"fmt"
"strings"
"strconv"
)
// 半角スペース区切りの size 個の整数データ1行を標準入力で受け取り配列で返す
func ReadIntsWithSize(size int) []int {
ints := make([]int, size)
for i:=0; i<size; i++ {
var num int
fmt.Scan(&num)
ints[i] = num
}
return ints
}
// 整数のスライスを、半角スペースで連結した文字列に変換する
func JoinIntsWithDelimiter(ints []int, delimiter string) string {
strs := make([]string, len(ints))
for i, num := range ints {
strs[i] = strconv.Itoa(num)
}
return strings.Join(strs, delimiter)
}
func main(){
var n int // データ行数
fmt.Scan(&n)
arr := make([][]int, 0) // サイズ0の二次元スライスarrの準備
// 1行のデータをスライスrowに格納し、arrにappendする
// これをn回繰り返す
for i:=0; i<n; i++ {
var size int // 各行の1つ目の整数で列サイズが与えられる
fmt.Scan(&size)
var row []int
row = ReadIntsWithSize(size)
arr = append(arr, row)
}
for j:=0; j<n; j++ {
fmt.Println(JoinIntsWithDelimiter(arr[j], " "))
}
}
以上で標準入力メニューは終了です。