問題
GPT 系のトークナイザはバイトペアエンコーディングを使います。1文字ずつから始め、最も多い隣どうしのペアを新しい記号へ繰り返しマージします。
wordsの各単語を文字に分割します。繰り返し現れる単語は複数回数えます。- すべての単語で、隣接する記号のペアをすべて数えます。
- 最も頻度の高いペアを選びます。同数なら、(1つ目の記号、2つ目の記号)を文字列として比較して最小のものを選びます。
- そのペアの出現を左から右へすべてマージした記号に置き換え、マージした記号を記録します。
- これを
num_merges回繰り返します。2つ以上の記号を持つ単語がなくなったら早めに終了します。
bpe_merges(words, num_merges) を実装してください。
入力
words: 学習用の単語(小文字)。
num_merges: 学習するマージの回数。
出力
マージした記号を学習した順に返してください。
制約
1 ≤ 単語数 ≤ 1,000、1 ≤ 各単語の長さ ≤ 30
0 ≤ num_merges ≤ 200
例
例 1
入力:
words = ["low", "lower", "lowest"]
num_merges = 2
期待される出力:
expected = ["lo", "low"]
入力:
std::vector<std::string> words = {"low", "lower", "lowest"};
long long num_merges = 2;
期待される出力:
std::vector<std::string> expected = {"lo", "low"};
入力:
string[] words = new string[] {"low", "lower", "lowest"};
long num_merges = 2;
期待される出力:
string[] expected = new string[] {"lo", "low"};
解説
ペア:"l o" と "o w" がどちらも3回です。同数なので "l o" を選び("l" < "o")、"lo" になります。次に "lo w" が3回現れ、"low" になります。結果:["lo", "low"]。
例 2
入力:
words = ["aaa"]
num_merges = 3
期待される出力:
expected = ["aa", "aaa"]
入力:
std::vector<std::string> words = {"aaa"};
long long num_merges = 3;
期待される出力:
std::vector<std::string> expected = {"aa", "aaa"};
入力:
string[] words = new string[] {"aaa"};
long num_merges = 3;
期待される出力:
string[] expected = new string[] {"aa", "aaa"};
解説
"aaa" にはペア "a a" が2回あります。左から右へマージすると "aa" + "a" になります。次に "aa a" が "aaa" にマージされ、単語は1つの記号だけになるので、3回目のマージは何もしません。結果:["aa", "aaa"]。
参考資料
この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。