Edited at

golangの競技プログラミング用の実践メモ

More than 1 year has passed since last update.

必要な時に思い出したい操作をメモ。あと似たような操作はこれ起点にググれるように。

一部パッケージは省略しています。


標準入力

package main

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

var sc = bufio.NewScanner(os.Stdin)

func read() string {
sc.Scan()
return sc.Text()
}

func main() {
sc.Split(bufio.ScanWords) // スペース区切りの設定
// sc.Split(bufio.ScanLines) // 一行丸ごと読む設定
n, _ := strconv.Atoi(read()) // int
str := read() // string

// array
a := make([]int, n)
for i := 0; i < n; i++ {
a[i], _ = strconv.Atoi(read())
}

// map
m := map[int]int{}
for i := 0; i < n; i++ {
m[i], _ = strconv.Atoi(read())
}

// 中身の確認用
fmt.Println(n, str, a, m)
}

基本の処理です。コピペで使えるように全文貼っておきます。


標準入力(一度に最後まで読む場合)

sc := bufio.NewScanner(os.Stdin)

a := []string{}
for sc.Scan() {
a = append(a, sc.Text())
}

入力値から入力の終わりがわからない場合はこっち。


文字列を一文字ずつ舐める

str := "hello"

for i, v := range str {
fmt.Println(i, string(v))
}


文字列を指定した文字で分割

str := "23x2x97x0"

fmt.Println(strings.Split(str, "x"))

ちなみに、ホワイトスペースで区切るなら strings.Fields(string) を使います。


スライスとマップの宣言

array1 := []int{} // 中身を入れて宣言できる

array2 := make([]int, 0) // 長さを指定して宣言できる
m := map[string]bool{}

まだ忘れがちなのでメモ。


指定した位置の要素を削除

func delete(a []int, i int) []int {

a = append(a[:i], a[i+1:]...)
return a
}
// a = delete(a, i)

func delete2(a *[]int, i int) {

tmp := *a
*a = append(tmp[:i], tmp[i+1:]...)
}
// delete2($a, i)

二種類書いておきます。条件にもよりますが、大抵の場合は上の方が高速です。

※mapならdelete(m, key)で消せます。

※じゃあmapでいい気がしますが、ソートが使えなかったりrangeで取り出す順番がランダムだったりするので使い分けですね。


ソート

array := []int{5, 1, 4, 2, 3}

sort.Sort(sort.IntSlice(array))

[]intの場合はこれ。


すでに走査した値を記憶する

type point struct {

x, y int
}

func (e point) key() string {
return fmt.Sprintf("%v", e)
}

func main() {
visited := map[string]bool{}

pt := point{0, 0}

key := pt.key()
if visited[key] {
// すでに到達済みの場合の処理
}
visited[key] = true

// まだ到達していない場合の処理
// etc...

// 中身の確認用
// fmt.Println(visited)
}

手っ取り早く枝刈りする場合に。必要に応じてkeyの表現を変えて使います。


スライスの内容まで見る比較

reflect.DeepEqual(array1, array2)

あまり使わなそうですが必要になったので。