Go
golang

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)

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