06. 集合
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,'se'というbi-gramがXおよびYに含まれるかどうかを調べよ
###Go
package main
import "fmt"
// n-gram
func nGram(target string,n int) []string {
var result []string
var len = len(target) - n + 1
for i := 0 ; i<len ; i++ {
result = append(result,target[i:i + n])
}
return result
}
// 配列の重複を削除
func single(src []string) []string {
m := make(map[string]bool)
s := make([]string,0,0)
for _,s1 := range(src) {
m[s1] = true
}
for s2,_ := range(m) {
s = append(s,s2)
}
return s;
}
// 積集合、差集合、"se" 存在チェック
func ans(x,y []string) ([]string,[]string,bool,bool) {
m := make(map[string]bool)
se := make([]string,0,0)
sa := make([]string,0,0)
seb := false
sab := false
// y を map 化
for _,s1 := range(y) {
m[s1] = true
}
// x を ループ
for _, s2 := range(x) {
// x = y のチェック
if m[s2] {
// 存在するので積
se = append(se, s2)
// X に se が含まれてるかチェック
if s2 == "se" {
seb = true
}
} else {
// 存在しないので差
sa = append(sa, s2)
// Y に se が含まれてるかチェック
if s2 == "se" {
seb = true
}
}
}
return se,sa,seb,sab;
}
func main() {
x := single(nGram("paraparaparadise",2))
y := single(nGram("paragraph",2))
fmt.Printf("X: %q\n",x)
fmt.Printf("Y: %q\n",y)
wa := single(append(x, y...))
fmt.Printf("和集合: %q\n",wa)
se,sa,seb,sab := ans(x,y)
fmt.Printf("積集合: %q\n",se)
fmt.Printf("差集合: %q\n",sa)
fmt.Printf("seがXに含まれる: %t\n",seb)
fmt.Printf("seがYに含まれる: %t\n",sab)
}
###python
# -*- coding: utf-8 -*-
# 指定されたリストからn-gramを作成
def n_gram(target, n):
result = []
for i in range(0, len(target) - n + 1):
result.append(target[i:i + n])
return result
# 集合の作成
set_x = set(n_gram('paraparaparadise', 2))
print('X:' + str(set_x))
set_y = set(n_gram('paragraph', 2))
print('Y:' + str(set_y))
# 和集合
set_or = set_x | set_y
print('和集合:' + str(set_or))
# 積集合
set_and = set_x & set_y
print('積集合:' + str(set_and))
# 差集合
set_sub = set_x - set_y
print('差集合:' + str(set_sub))
# 'se'が含まれるか?
print('seがXに含まれる:' + str('se' in set_x))
print('seがYに含まれる:' + str('se' in set_y))
###Javascript
// nGram を作成(05. n-gram の nagtkkさん のを転用)
function nGram(str, n, del) {
return str.split(del)
.map((_, i, a) => a.slice(i, i + n).join(del))
.slice(0, 1 - n);
}
// 集合の作成(重複を削除)
var x = nGram('paraparaparadise', 2,'').filter(function (x, i, self) {
return self.indexOf(x) === i;
});
console.log('X:',x);
// 集合の作成(重複を削除)
var y = nGram('paragraph', 2,'').filter(function (x, i, self) {
return self.indexOf(x) === i;
});
console.log('X:',y);
var wa = x.concat(y).filter(function (x, i, self) {
return self.indexOf(x) === i;
});
console.log('和集合:',wa);
var se = x.concat(y).filter(function (x, i, self) {
return self.indexOf(x) !== i;
});
console.log('積集合:',se);
var sa = x.filter(function (x, i, self) {
return y.indexOf(x) === -1;
});
console.log('差集合:',sa);
console.log('seがXに含まれる:',x.indexOf("se") == -1 ? 'False' : 'True');
console.log('seがyに含まれる:',y.indexOf("se") == -1 ? 'False' : 'True');
まとめ
忙しくて投稿がおそくなりました。← 言い訳です。
すみません。@segavvy さんのをカンニングしました。
素人の言語処理100本ノック:06
配列の和集合、積集合、和集合って?。と調べてたら。
とても、わかりやすかったです。Python はそのまま。^^;;
見たら直しようがない?。
Javascript は、 lodash ライブラリを使って作ったがライブラリ無しで再作り直し。
nGram関数 は 05 から @nagtkk さんのを転用しました。
Go はかっこ悪いソースになってしまった。もっとスマートに書けるようにしたい。
しかし、Python 恐るべし。覚えると強そう。