言語処理100本ノック1章をkotlinで解いてみた(0..5)


学校がなくて暇だったのでkotlinをはじめてみました。
その練習を兼ねてやっていこうと思います。

00. 文字列の逆順

文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.
普通にString.reversed()をつかってるだけですね

fun main() {
    val s:String = "stressed"
    println(s.reversed())
}
//OutPut:desserts

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.
printは改行しないで出力する関数です。
substring(i-1,i)の部分はもっと簡潔に書きたいけどググる力が低いのか見つからない
4/30追記
@htsign さんにs[i-1]でいいと教えていただきました。ありがとうございます
たしかにsliceってありがちなのになんで思いつかなかったんでしょうね。過去の自分が謎です。

fun main() {
    val s:String = "パタトクカシー"
    for (i in arrayOf(1,3,5,7)) {
        print(s[i-1])
        //print(s.substring(i-1,i)
    }
    println()
}
//OutPut:パトカー

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.
パトカーとタクシーをList<Char>にしてzipというふたつのListをまとめるやつ(例えば、[0,1,2]というListに対して[1,2,3]をzipしたら[(0,1),(1,2),(2,3)]になる)

fun main() {
    val s1:List<Char> = "パトカー".toList()
    val s2:List<Char> = "タクシー".toList()
    for ((x,y) in s1.zip(s2)) {
        print("$x$y")
    }
    println()
}
//OutPut:パタトクカシーー

03. 円周率

“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.
みんな大好き正規表現でアルファベットを抽出して長さを出してます。

fun main() {
    val s:String = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
    val matchls = Regex("""\w+""").findAll(s)
    var mus:List<Int> = matchls.toList().map({it.value.length})
    println(mus.joinToString(" "))
}
//OutPut:3 1 4 1 5 9 2 6 5 3 5 8 9 7 9

04. 元素記号

“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.
ここではでないんですけどkotlinでの辞書型はmapOf(1 to 2)みたいにtoをつかうんですよね。慣れない...

fun main() {
    val s:List<String> = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.".split(" ")
    val mam:MutableMap<String,Int> = mutableMapOf()
    val arr:List<Int> = listOf(1,5,6,7,8,9,15,16,19).map({it-1})
    for (i in 0..(s.size-1)) {
        if (i in arr) {
            mam[s[i].substring(0,1)] = i+1
        }
        else {
            mam[s[i].substring(0,2)] = i+1
        }
    }
    println(mam)
}
//OutPut:{H=1, He=2, Li=3, Be=4, B=5, C=6, N=7, O=8, F=9, Ne=10, Na=11, Mi=12, Al=13, Si=14, P=15, S=16, Cl=17, Ar=18, K=19, Ca=20}

05. n-gram

与えられたシーケンス(文字列やリストなど)からn-gramを作る関数を作成せよ.この関数を用い,”I am an NLPer”という文から単語bi-gram,文字bi-gramを得よ.
言語処理100本ノック1章、初めて解いたときn-gramを知りませんでした。これ一般的なんでしょうかねえ

//文字
fun nGram(tg:List<Char>, n:Int):List<String> {
    val res:MutableList<String> = mutableListOf()
    for (i in 0..(tg.size-n)) {
        res.add(tg.slice(i..(i+n-1)).toString())
    }
    return res.toList()
}

//単語
fun nGram_(tg:List<String>, n:Int):List<String> {
    val res:MutableList<String> = mutableListOf()
    for (i in 0..(tg.size-n)) {
        res.add(tg.slice(i..(i+n-1)).toString())
    }
    return res.toList()
}

fun main() {
    val s:String = "I am an NLPer"
    //文字
    println(nGram(s.toList(), 2))
    //単語
    println(nGram_(s.split(" "), 2))
}
//OutPut:[[I,  ], [ , a], [a, m], [m,  ], [ , a], [a, n], [n,  ], [ , N], [N, L], [L, P], [P, e], [e, r]]
//OutPut:[[I, am], [am, an], [an, NLPer]]

次回

7..9は明日か明後日にはだします!!!お楽しみに!!!
書いたよ