LoginSignup
3
2

More than 3 years have passed since last update.

06. 集合

Last updated at Posted at 2019-12-04

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 恐るべし。覚えると強そう。

トップ

3
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2