このチートシートについて
「Trackなどのコードテスト」や「Atcoder」や「Paiza」などといった競技プログラミングでよく使われる処理をサンプルコードとして書いていきます。
また、何か追加情報やより良いものなど変更があった場合は更新していきます。
私自信が競技プログラミングを受けた時に、頻出したコードを随時更新していきます。
なので、実際には足りていないところもあると思います。
そこはご了承いただけると幸いです。
概要
自動の目次生成のあるがあるため必要ないかもしれないが、念の為目次の作成
No | 概要 |
---|---|
1 | 標準出力 |
2 | 標準入力 |
3 | 文字列分割して配列に格納 |
4 | 文字列、整数変換 |
5 | スライス |
6 | マップ |
7 | ソート |
標準出力
主に使われる、fmt.Println() と fmt.Printf() を紹介します。
fmt.Println()
package main
import "fmt"
func main() {
name := "佐藤"
age := 21
fmt.Println(name)
fmt.Println(name, age)
fmt.Println("名前は", name, "です。年齢は", age, "際です。")
}
佐藤
佐藤 21
名前は 佐藤 です。年齢は 21 際です。
fmt.Printf()
↑と同じようにこちらでも表示してみます。
package main
import "fmt"
func main() {
name := "佐藤"
age := 21
fmt.Printf("%s\n", name)
fmt.Printf("%s %d\n", name, age)
fmt.Printf("名前は%sです。年齢は%d際です。\n", name, age)
}
佐藤
佐藤 21
名前は佐藤です。年齢は21際です。
デフォルトフォーマット「%v」
Goでは、先ほど使用した「%s」や「%d」を使用せずに、「%v」でフォーマットすることができます。
package main
import "fmt"
func main() {
name := "佐藤"
age := 21
fmt.Printf("%v\n", name)
fmt.Printf("%v %v\n", name, age)
fmt.Printf("名前は%vです。年齢は%v際です。\n", name, age)
}
佐藤
佐藤 21
名前は佐藤です。年齢は21際です。
標準入力
標準入力する方法
fmt.Scan() で標準入力を行う
package main
import (
"fmt"
)
func main() {
var str string
fmt.Scan(&str) // データを格納する変数のアドレスを指定
fmt.Println(str)
}
123
123
競技プログラミングでは、スペースで区切って複数の文字列を取得しますが、このままだと取得できません。
abc def 123
abc
↑"def 123"が取得できていない!!
複数の文字列を取得する方法
変数を配列型にすると複数受けとることができます。
package main
import (
"fmt"
)
func main() {
vvar str [3]string
fmt.Scan(&str[0], &str[1], &str[2])
fmt.Println(str)
}
abc def 123
[abc def 123]
しかし、配列で3つまでと格納できないよう指定しているため、4つ目以降の文字列を取得するできなくなってしまいます。
上限なしで複数の文字列を取得する方法
bufioパッケージの**Newcanner()**メソッドを使います。
package main
import (
"bufio"
"fmt"
"os"
)
func main(){
scanner := bufio.NewScanner(os.Stdin) // 標準入力を受け付けるスキャナー
scanner.Scan() // 入力を取得する
fmt.Println(scanner.Text())
}
123 456 abc def ghi
123 456 abc def ghi
こちらは半角スペースも含めた文字列で複数の文字列を取得します。
複数行の文字列を入力する
先ほどを少し改良して1行だけでなく複数行の文字列を取得する方法です。
package main
import (
"bufio"
"fmt"
"os"
)
func main(){
var str []string
n := 3
scanner := bufio.NewScanner(os.Stdin) // 標準入力を受け付けるスキャナー
for i := 0; i < n; i++ {
scanner.Scan()
str = append(str, scanner.Text())
}
for i, v := range str {
fmt.Printf("line[%d]: %v\n", i, v)
}
}
123 456 789
abc def ghi
ABC DEF GHI
line[0]: 123 456 789
line[1]: abc def ghi
line[2]: ABC DEF GHI
複数行の文字列を入力する(その2)
最後にTrackさんでのコードテストであった標準入力を紹介します。
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
func main() {
lines := getStdin()
for i, v := range lines {
fmt.Printf("line[%d]: %v\n", i, v)
}
}
func getStdin() []string {
stdin, _ := ioutil.ReadAll(os.Stdin)
return strings.Split(strings.TrimRight(string(stdin), "\n"), "\n")
}
123 456 789
abc def ghi
ABC DEF GHI
line[0]: 123 456 789
line[1]: abc def ghi
line[2]: ABC DEF GHI
こちらは、回数制限がないので、自由に複数行の文字列を取得することができます。
ファイル読み込み
main.goと同じディレクトリに「test.txt」を用意しました。
テスト用ファイル
こんにちは!
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
)
func main() {
f, err := os.Open("./test.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
log.Fatal(err)
}
str := string(b)
fmt.Println(str)
}
テスト用ファイル
こんにちは!
文字列分割して配列に格納
arr := strings.Split(str, " ")
package main
import (
"fmt"
"strings"
)
func main() {
str := "abc def ghi"
fmt.Println("文字列: ", str)
arr := strings.Split(str, " ")
fmt.Println("配列: ", arr)
}
文字列: abc def ghi
配列: [abc def ghi]
文字列、整数変換
num, _ := strconv.Atoi("123")
str, _ := strconv.Itoa(123)
package main
import (
"fmt"
"strings"
)
func main() {
strNum := "123"
fmt.Println(strNum, reflect.TypeOf(strNum))
num, _ := strconv.Atoi(strNum)
fmt.Println(num, reflect.TypeOf(num))
}
123 string
123 int
スライス
初期化
var sInt []int
var sStr []string
var sInt = []int{1, 2, 3}
var sStr = []string{"apple", "banana", "lemon"}
追加
sInt = append(sInt, 100)
package main
func main() {
var sInt = []int{1, 2, 3}
sInt = append(sInt, 100)
fmt.Println(sInt)
}
[1 2 3 100]
長さ
var sInt = []int{1, 2, 3}
len(sInt) // 3
マップ
初期化
makeMap := make(map[int]string)
追加
makeMap[1] = "apple"
makeMap[2] = "banana"
package main
import "fmt"
func main() {
makeMap := make(map[int]string)
makeMap[1] = "apple"
makeMap[2] = "banana"
fmt.Println(makeMap)
fmt.Println("makeMap[1]: ", makeMap[1])
}
map[1:apple 2:banana]
makeMap[1]: apple
ソート
スライスのソート
整数のソート
// 昇順
sort.Ints(sInt)
// 降順
sort.Sort(sort.Reverse(sort.IntSlice(sInt)))
package main
import (
"fmt"
"sort"
)
func main() {
sInt := []int{3, 2, 6, 1, 6, 3, 9, 3, 2, 1}
// 昇順
sort.Ints(sInt)
fmt.Println("昇順: ", sInt)
// 降順
sort.Sort(sort.Reverse(sort.IntSlice(sInt)))
fmt.Println("降順: ", sInt)
}
昇順: [1 1 2 2 3 3 3 6 6 9]
降順: [9 6 6 3 3 3 2 2 1 1]
文字列のソート
// 昇順
sort.Strings(sStr)
// 降順
sort.Sort(sort.Reverse(sort.StringSlice(sStr)))
package main
import (
"fmt"
"sort"
)
func main() {
sStr := []string{"b", "a", "z", "r", "d"}
// 昇順
sort.Strings(sStr)
fmt.Println("昇順: ", sStr)
// 降順
sort.Sort(sort.Reverse(sort.StringSlice(sStr)))
fmt.Println("降順: ", sStr)
}
昇順: [a b d r z]
降順: [z r d b a]
マップのソート
整数のキー順
// スライスにキーだけを格納してソートする
slice := make([]int, len(map1))
index := 0
for key := range map1 {
slice[index] = key
index++
}
sort.Ints(slice)
package main
import (
"fmt"
"sort"
)
func main() {
map1 := map[int]string{
3: "e", 2: "q", 5: "a", 1: "r",
}
// キーをソートする
slice := make([]int, len(map1))
index := 0
for key := range map1 {
slice[index] = key
index++
}
sort.Ints(slice)
//列挙
for _, key := range slice {
fmt.Println(key, map1[key])
}
}
1 r
2 q
3 e
5 a
文字列のキー順
// スライスにキーだけを格納してソートする
slice := make([]string, len(map1))
index := 0
for key := range map1 {
slice[index] = key
index++
}
sort.Strings(slice)
package main
import (
"fmt"
"sort"
)
func main() {
map1 := map[string]int{
"z": 1, "a": 10, "c": 4, "d": 5,
}
// キーをソートする
slice := make([]string, len(map1))
index := 0
for key := range map1 {
slice[index] = key
index++
}
sort.Strings(slice)
//列挙
for _, key := range slice {
fmt.Println(key, map1[key])
}
}
a 10
c 4
d 5
z 1