私は最近、文字のタイルを使用して単語を作成するゲームを書き始めました。ゲームを作成するには、英語の通常の単語全体の文字の頻度を知る必要がありました。これにより、便利な文字タイルのセットを提示できました。文字の頻度はウィキペディアを含むさまざまな場所で議論されていますが、私は文字の頻度を自分で計算したかったのです。
Linuxは、/usr/share/dict/words
内の単語のリストを提供します ファイルなので、使用する可能性のある単語のリストがすでにあります。 words
ファイルには、必要な単語がたくさん含まれていますが、含まれていない単語もいくつかあります。複合語(ハイフンやスペースなし)または適切な名詞(大文字なし)ではないすべての単語のリストが必要でした。そのリストを取得するには、grep
を実行します 小文字のみで構成される行のみを引き出すコマンド:
$ grep '^[a-z]*$' /usr/share/dict/words
この正規表現はgrep
に要求します 小文字のみのパターンに一致します。文字^
および$
パターン内は、それぞれ行の開始と終了を表します。 [a-z]
グループ化は小文字のaのみに一致します zへ 。
出力の簡単なサンプルは次のとおりです。
$ grep '^[a-z]*$' /usr/share/dict/words | head
a
aa
aaa
aah
aahed
aahing
aahs
aal
aalii
aaliis
その他のLinuxリソース
- Linuxコマンドのチートシート
- 高度なLinuxコマンドのチートシート
- 無料のオンラインコース:RHELの技術概要
- Linuxネットワーキングのチートシート
- SELinuxチートシート
- Linuxの一般的なコマンドのチートシート
- Linuxコンテナとは何ですか?
- 最新のLinux記事
そして、はい、それらはすべて有効な言葉です。たとえば、「aahed」は、リラクゼーションの場合のように、「aah」の過去形の感嘆符です。そして「aalii」はふさふさした熱帯低木です。
ここで、gawk
を作成する必要があります。 各単語の文字を数える作業を実行し、見つかった各文字の相対頻度を出力するスクリプト。
文字を数える
gawk
の文字を数える1つの方法 各入力行の各文字を繰り返し処理し、各文字の出現回数をカウントすることです a zへ 。 substr
関数は、より大きな文字列から、1文字など、指定された長さの部分文字列を返します。たとえば、このコード例では、各文字c
を評価します。 入力から:
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
}
}
グローバル文字列LETTERS
で開始する場合 アルファベットが含まれているので、index
を使用できます アルファベットの1文字の位置を見つける関数。 gawk
を展開します 文字のみを評価するコード例a zへ 入力:
BEGIN { LETTERS = "abcdefghijklmnopqrstuvwxyz" }
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
ltr = index(LETTERS, c);
}
}
index関数は、LETTERS
から最初に出現する文字を返すことに注意してください。 文字列。最初の文字が1で始まり、見つからない場合は0で始まります。 26要素の長さの配列がある場合は、その配列を使用して各文字の出現回数を数えることができます。これをコード例に追加してインクリメントします(++
を使用) )入力に表示される各文字の数:
BEGIN { LETTERS = "abcdefghijklmnopqrstuvwxyz" }
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
ltr = index(LETTERS, c);
if (ltr > 0) {
++count[ltr];
}
}
}
相対度数の印刷
gawk
の後 スクリプトはすべての文字をカウントします。見つかった各文字の頻度を印刷したいと思います。入力からの各文字の総数ではなく、相対頻度に関心があります。 各文字の。相対度数は、出現回数が最も少ない文字( q の文字など)になるようにカウントをスケーリングします。 )は1に設定され、他の文字はそれに関連しています。
文字aのカウントから始めましょう 、次にその値を他の各文字のカウントと比較します b zへ :
END {
min = count[1]; for (ltr = 2; ltr <= 26; ltr++) {
if (count[ltr] < min) {
min = count[ltr];
}
}
}
そのループの終わりに、変数min
任意の文字の最小数が含まれます。これを使用して、各文字の相対度数を印刷するためのカウントのスケールを提供できます。たとえば、出現回数が最も少ない文字が qの場合 、次にmin
qと等しくなります カウント。
次に、各文字をループして、相対的な頻度で印刷します。各カウントをmin
で割ります 相対度数を印刷します。つまり、最小カウントの文字は相対度数1で印刷されます。別の文字が最小カウントの2倍の頻度で表示される場合、その文字の相対度数は2になります。私だけですここで整数値に関心があるので、2.1と2.9は私の目的では2と同じです:
END {
min = count[1]; for (ltr = 2; ltr <= 26; ltr++) {
if (count[ltr] < min) {
min = count[ltr];
}
}
for (ltr = 1; ltr <= 26; ltr++) {
print substr(LETTERS, ltr, 1), int(count[ltr] / min);
}
}
すべてをまとめる
今、私はgawk
を持っています 入力内の文字の相対頻度をカウントできるスクリプト:
#!/usr/bin/gawk -f
# only count a-z, ignore A-Z and any other characters
BEGIN { LETTERS = "abcdefghijklmnopqrstuvwxyz" }
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
ltr = index(LETTERS, c);
if (ltr > 0) {
++count[ltr];
}
}
}
# print relative frequency of each letter
END {
min = count[1]; for (ltr = 2; ltr <= 26; ltr++) {
if (count[ltr] < min) {
min = count[ltr];
}
}
for (ltr = 1; ltr <= 26; ltr++) {
print substr(LETTERS, ltr, 1), int(count[ltr] / min);
}
}
これをletter-freq.awk
コマンドラインから簡単に使用できるようにします。
必要に応じて、chmod +x
を使用することもできます ファイルを独自に実行可能にします。 #!/usr/bin/gawk -f
最初の行は、Linuxが/usr/bin/gawk
を使用してスクリプトとして実行することを意味します プログラム。そして、gawk
コマンドラインは-f
を使用します スクリプトとして使用するファイルを指定するには、-f
をぶら下げる必要があります。 letter-freq.awk
を実行するようにします シェルでは、/usr/bin/gawk -f letter-freq.awk
を実行していると適切に解釈されます。 代わりに。
いくつかの簡単な入力でスクリプトをテストできます。たとえば、アルファベットをgawk
にフィードした場合 スクリプトでは、各文字の相対頻度は1である必要があります:
$ echo abcdefghijklmnopqrstuvwxyz | gawk -f letter-freq.awk
a 1
b 1
c 1
d 1
e 1
f 1
g 1
h 1
i 1
j 1
k 1
l 1
m 1
n 1
o 1
p 1
q 1
r 1
s 1
t 1
u 1
v 1
w 1
x 1
y 1
z 1
その例を繰り返しますが、文字 eのインスタンスを追加します 文字eを印刷します 相対度数が2で、1文字おきに1:
$ echo abcdeefghijklmnopqrstuvwxyz | gawk -f letter-freq.awk
a 1
b 1
c 1
d 1
e 2
f 1
g 1
h 1
i 1
j 1
k 1
l 1
m 1
n 1
o 1
p 1
q 1
r 1
s 1
t 1
u 1
v 1
w 1
x 1
y 1
z 1
そして今、私は大きな一歩を踏み出すことができます! grep
を使用します /usr/share/dict/words
を使用したコマンド ファイルを作成し、すべて小文字で綴られたすべての単語の文字頻度を特定します:
$ grep '^[a-z]*$' /usr/share/dict/words | gawk -f letter-freq.awk
a 53
b 12
c 28
d 21
e 72
f 7
g 15
h 17
i 58
j 1
k 5
l 36
m 19
n 47
o 47
p 21
q 1
r 46
s 48
t 44
u 25
v 6
w 4
x 1
y 13
z 2
/usr/share/dict/words
内のすべての小文字の単語 ファイル、文字 j 、 q 、および x 最も頻度が低い。文字z また、かなりまれです。当然のことながら、文字 e 最も頻繁に使用されます。