【Go】AtCoderでよく使う関数
はじめに
goでAt Coderを解くにあたってC++で書かれた解説コードをGoに焼き直す作業を頻繁に行っています。その際「C++に有ってgoにはない」メソッドや文法が多くて結構困ります
冗長なだけなら「goだし仕方ないか」で済むのですが、明らかにあった方が良いメソッドが標準パッケージに搭載されていない事もしばしば
そこで幾つか自分で実装してみよう!
配列操作
C++のvectorやiteratorで使われる関数をもうちょい足したい
count
func Count(s []int, n int) int { var cnt int for _, v := range s { if v == n { cnt++ } } return cnt }
unique
func Unique(s []int) []int { uniq := make([]int, len(s)) m := make(map[int]bool) cnt := 0 for _, ele := range s { if !m[ele] { m[ele] = true uniq[cnt] = ele cnt++ } } return uniq[:cnt] }
文字列に対する関数
find
第1引数の集合に第2引数の値が存在した場合、そのindexを返す関数
引数にinterface{}
型を取り、reflectで型判別しながら異なる処理を呼び出すことで実装できますが、実行速度が大幅に遅くなる為文字列に絞って実装します。
可変長配列ならソートしてからsort.Search
で二分探索すれば良いはず
func find(str string, char string) int { for i := range str { if string(str[i]) == char { return i } } return -1 }
O(N)
汎用計算関数
std::abs
std::max
std::min
std::pow
std::sqrt
func max(x, y int) int { if x > y { return x } return y } func min(x, y int) int{ if x > y { return y } return x } func abs(a int) int { return int(math.Abs(float64(a))) } func pow(p, q int) int { return int(math.Pow(float64(p), float64(q))) } func squart(x, y int) float64 { dif := x*x - y*y return math.Sqrt(float64(dif)) } func pow(x, y int) int { return int(math.Pow(float64(x), float64(y))) // 2, 3 = 8 // 10, 2 = 100
permulation
順列を扱う際にお世話になるメソッドです
func Factorial(n int)(result int) { if (n > 0) { result = n * Factorial(n-1) return result } return 1 } /* fmt.Println(0, intSlice) for i := 1; nextPermutation(sort.IntSlice(intSlice)); i++ { fmt.Println(i, intSlice) } */ func nextPermutation(x sort.Interface) bool { n := x.Len() - 1 if n < 1 { return false } j := n - 1 for ; !x.Less(j, j+1); j-- { if j == 0 { return false } } l := n for !x.Less(j, l) { l-- } x.Swap(j, l) for k, l := j+1, n; k < l; { x.Swap(k, l) k++ l-- } return true }
Factorialは日本語で「階乗」の意味でN!を算出します。(3! は 3、10! は 45)
次にnextPermulationはC++のnextPermulation
と同じ挙動です。順列の全パターンを出力し、最大値まで並べ終えるとfalseを返します
最後に
同じ様なコンセプトで「標準パッケージにないけど欲しい」関数があれば是非教えていただきたいです!
c++ちゃんと勉強したい