06. 集合

## 06. 集合
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ

###Go
```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
```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
```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](https://qiita.com/segavvy/items/209bf27d4cee51f60f99)
配列の和集合、積集合、和集合って？。と調べてたら。
とても、わかりやすかったです。Python はそのまま。^^;;
見たら直しようがない？。

Javascript は、 lodash ライブラリを使って作ったがライブラリ無しで再作り直し。
nGram関数 は 05 から @nagtkk さんのを転用しました。

Go はかっこ悪いソースになってしまった。もっとスマートに書けるようにしたい。

しかし、Python 恐るべし。覚えると強そう。

[トップ](https://qiita.com/naoshin1984/items/3d7814e2f8eb01eea8dd)