100knock #48
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
package main
import (
"./fileio"
"fmt"
"os"
"strconv"
"strings"
)
type Morph struct {
surface string
base string
pos string
pos1 string
}
type Chunk struct {
morphs []Morph
dst int
srcs []int
}
func parseArticle(lines []string) [][]Chunk {
article := make([][]Chunk, 0)
morphemes := make([]Morph, 0)
sentence := make([]Chunk, 0)
var chunk Chunk
for _, line := range lines {
if line == "EOS" {
if len(morphemes) > 0 {
chunk.morphs = morphemes
sentence = append(sentence, chunk)
morphemes = make([]Morph, 0)
}
if len(sentence) > 0 {
initSourceIndex(sentence)
article = append(article, sentence)
sentence = make([]Chunk, 0)
}
continue
}
if line[0] == '*' {
if len(morphemes) > 0 {
chunk.morphs = morphemes
sentence = append(sentence, chunk)
morphemes = make([]Morph, 0)
}
//* 文節番号 係り先の文節番号(係り先なし:-1) 主辞の形態素番号/機能語の形態素番号 係り関係のスコア
words := strings.Split(line, " ")
// Remove "D"
dst, err := strconv.Atoi(words[2][:len(words[2])-1])
if err != nil {
panic(err)
}
chunk = initChunk(chunk, dst)
continue
}
//表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音
word := strings.Split(line, "\t")
words := strings.Split(word[1], ",")
morpheme := Morph{
surface: word[0],
base: words[6],
pos: words[0],
pos1: words[1],
}
morphemes = append(morphemes, morpheme)
}
return article
}
func initChunk(chunk Chunk, dst int) Chunk {
chunk.morphs = make([]Morph, 0)
chunk.dst = dst
chunk.srcs = make([]int, 0)
return chunk
}
func initSourceIndex(sentence []Chunk) {
for i, chunk := range sentence {
if chunk.dst < 0 {
continue
}
sentence[chunk.dst].srcs = append(sentence[chunk.dst].srcs, i)
}
}
func containNoun(morphs []Morph) bool {
for _, morph := range morphs {
if morph.pos == "名詞" {
return true
}
}
return false
}
func joinPhrase(morphs []Morph) string {
joinString := ""
for _, morph := range morphs {
if morph.pos == "記号" {
continue
}
joinString += morph.surface
}
return joinString
}
func joinArrow(sentence []Chunk, chunk Chunk) string {
phrases := ""
chunkDst := chunk.dst
for chunkDst != -1 {
phrases += joinPhrase(sentence[chunkDst].morphs) + " -> "
chunkDst = sentence[chunkDst].dst
}
return phrases
}
func printNounToRoot(sentence []Chunk) {
for _, chunk := range sentence {
if containNoun(chunk.morphs) == false {
continue
}
phrases := joinArrow(sentence, chunk)
if phrases != "" {
phrases = strings.TrimRight(phrases, " -> ")
fmt.Printf("%s -> %s\n", joinPhrase(chunk.morphs), phrases)
}
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: main <filepath>")
os.Exit(1)
}
lines := fileio.ReadFileAllLines(os.Args[1])
article := parseArticle(lines)
for _, sentence := range article {
printNounToRoot(sentence)
}
}
Go
INFO