Lapis Lazuli

technical blog for web developer

【Go】Goで競技プログラミング(標準入力について)

競技プログラミングでのGo

前回に続き、Goで競技プログラミングを攻略しているので、競プロをやってる人にはおなじみの標準入力から文字列を取得する方法を書きます。
僕はGoで書いているのでGoのやり方になりますが、Goは他の言語に比べると文字列を扱う機能が若干貧弱だったりします。
標準パッケージでやろうと思えばやれるのですが、こと競プロにおいてはC++が最大派閥だと思いますので、断然こちらのほうが充実しています。

なぜGoなのか

自分が使える言語で最速がGoだからという理由に限ります(笑)
おそらくGoでAtCoderやる人ってあまり居ないじゃないか(主観)っていうくらいのマイナーな言語になります。
どうやら青以上のランクになってくると、ほぼC++らしいので、まぁそれくらいまではGoでもいいかなと。
それくらいならRubyとかのスクリプトでも戦えるみたいです。

速度的にはほぼ差は無いと思いますが、やはりライブラリの充実度の違いが痛くなってくる予感はしてます。
が、普通に入力を受け取って順番に処理したりという、ビギナーコンテストで求められる計算なら、そのデメリットもあまりありません。

ということで、その標準入力を取る方法を紹介します。

Scanを使う

これが簡単かつシンプルです。

package main
 
import (
	"fmt"
)

func main() {
	var a string
	fmt.Scan(&a)
}

これで入力が一行読み取って文字列がaに入ってきます。
複数行ある場合はScanを何度もやればいいだけです。
速度自体はあまり早くないので、数字などの値を取るだけとか、短い文字を取る場合に使える感じです。上位レベルの問題に出てくる長い文字列に使うと制限時間オーバーします(経験済)
ただし気をつけないといけないのが、文字列の途中に空白があった場合、そこで区切られて値を格納します。
なので複数の変数のアドレスを渡してあげる必要があります。

func main() {
	var a string
	var b string
	fmt.Scan(&a &b)
}

これで"3 5"のような区切りの文字列も取得出来ます。
またScanfを使ってフォーマット指定も出来ます。

func main() {
	var a string
	var b string
	fmt.Scanf("%s %s", &a &b)
}

今の所これしか使ってないのですが、他にあるみたいなので(bufio使う方法とか)
使う場面に遭遇したら使ってみようと思います。