Saya baru-baru ini mulai menulis permainan di mana Anda membangun kata-kata menggunakan ubin huruf. Untuk membuat game, saya perlu mengetahui frekuensi huruf di seluruh kata biasa dalam bahasa Inggris, jadi saya bisa menyajikan satu set ubin huruf yang berguna. Frekuensi huruf dibahas di berbagai tempat, termasuk di Wikipedia, tetapi saya ingin menghitung sendiri frekuensi hurufnya.
Linux menyediakan daftar kata di /usr/share/dict/words
file, jadi saya sudah memiliki daftar kemungkinan kata-kata untuk digunakan. words
file berisi banyak kata yang saya inginkan, tetapi beberapa yang tidak saya inginkan. Saya ingin daftar semua kata yang bukan kata majemuk (tanpa tanda hubung atau spasi) atau kata benda (tanpa huruf besar). Untuk mendapatkan daftar itu, saya dapat menjalankan grep
perintah untuk menarik hanya baris yang hanya terdiri dari huruf kecil:
$ grep '^[a-z]*$' /usr/share/dict/words
Ekspresi reguler ini menanyakan grep
untuk mencocokkan pola yang hanya huruf kecil. Karakter ^
dan $
dalam pola masing-masing mewakili awal dan akhir baris. [a-z]
pengelompokan hanya akan cocok dengan huruf kecil a ke z .
Berikut ini contoh cepat output:
$ grep '^[a-z]*$' /usr/share/dict/words | head
a
aa
aaa
aah
aahed
aahing
aahs
aal
aalii
aaliis
Lebih banyak sumber daya Linux
- Lembar contekan perintah Linux
- Lembar contekan perintah Linux tingkat lanjut
- Kursus online gratis:Ikhtisar Teknis RHEL
- Lembar contekan jaringan Linux
- Lembar contekan SELinux
- Lembar contekan perintah umum Linux
- Apa itu container Linux?
- Artikel Linux terbaru kami
Dan ya, itu semua adalah kata-kata yang valid. Misalnya, "aahed" adalah bentuk lampau dari seruan "aah", seperti dalam relaksasi. Dan "aalii" adalah semak tropis lebat.
Sekarang saya hanya perlu menulis gawk
skrip untuk melakukan pekerjaan menghitung huruf dalam setiap kata, dan kemudian mencetak frekuensi relatif dari setiap huruf yang ditemukan.
Menghitung huruf
Salah satu cara menghitung huruf di gawk
adalah untuk mengulangi setiap karakter di setiap baris input dan menghitung kemunculan setiap huruf a ke z . substr
function akan mengembalikan substring dengan panjang tertentu, seperti satu huruf, dari string yang lebih besar. Misalnya, contoh kode ini akan mengevaluasi setiap karakter c
dari masukan:
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
}
}
Jika saya mulai dengan string global LETTERS
yang berisi alfabet, saya dapat menggunakan index
berfungsi untuk mencari letak satu huruf dalam alfabet. Saya akan memperluas gawk
contoh kode untuk mengevaluasi hanya huruf a ke z di masukan:
BEGIN { LETTERS = "abcdefghijklmnopqrstuvwxyz" }
{
len = length($0); for (i = 1; i <= len; i++) {
c = substr($0, i, 1);
ltr = index(LETTERS, c);
}
}
Perhatikan bahwa fungsi indeks mengembalikan kemunculan huruf pertama dari LETTERS
string, dimulai dengan 1 pada huruf pertama, atau nol jika tidak ditemukan. Jika saya memiliki array yang panjangnya 26 elemen, saya dapat menggunakan array untuk menghitung kemunculan setiap huruf. Saya akan menambahkan ini ke contoh kode saya untuk menambah (menggunakan ++
) hitungan untuk setiap huruf seperti yang muncul di input:
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];
}
}
}
Frekuensi relatif pencetakan
Setelah gawk
skrip menghitung semua huruf, saya ingin mencetak frekuensi setiap huruf yang ditemukan. Saya tidak tertarik pada jumlah total setiap huruf dari input, melainkan frekuensi relatif dari setiap huruf. Frekuensi relatif menskalakan jumlah sehingga huruf dengan kemunculan paling sedikit (seperti huruf q ) disetel ke 1, dan huruf lainnya relatif terhadap itu.
Saya akan mulai dengan menghitung huruf a , lalu bandingkan nilai tersebut dengan jumlah untuk setiap huruf lainnya b ke z :
END {
min = count[1]; for (ltr = 2; ltr <= 26; ltr++) {
if (count[ltr] < min) {
min = count[ltr];
}
}
}
Di akhir perulangan itu, variabel min
berisi jumlah minimum untuk setiap huruf. Saya dapat menggunakannya untuk memberikan skala hitungan untuk mencetak frekuensi relatif setiap huruf. Misalnya, jika huruf dengan kemunculan terendah adalah q , lalu min
akan sama dengan q hitung.
Kemudian saya mengulang setiap huruf dan mencetaknya dengan frekuensi relatifnya. Saya membagi setiap hitungan dengan min
untuk mencetak frekuensi relatif, yang berarti huruf dengan hitungan terendah akan dicetak dengan frekuensi relatif 1. Jika huruf lain muncul dua kali lebih sering dari hitungan terendah, huruf tersebut akan memiliki frekuensi relatif 2. I'm only tertarik dengan nilai integer di sini, jadi 2.1 dan 2.9 sama dengan 2 untuk tujuan saya:
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);
}
}
Menggabungkan semuanya
Sekarang saya punya gawk
skrip yang dapat menghitung frekuensi relatif huruf dalam inputnya:
#!/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);
}
}
Saya akan menyimpannya ke file bernama letter-freq.awk
sehingga saya dapat menggunakannya dengan lebih mudah dari baris perintah.
Jika mau, Anda juga dapat menggunakan chmod +x
untuk membuat file dapat dieksekusi sendiri. #!/usr/bin/gawk -f
pada baris pertama berarti Linux akan menjalankannya sebagai skrip menggunakan /usr/bin/gawk
program. Dan karena gawk
baris perintah menggunakan -f
untuk menunjukkan file mana yang harus digunakan sebagai skrip, Anda memerlukan -f
yang menggantung itu sehingga mengeksekusi letter-freq.awk
di shell akan ditafsirkan dengan benar sebagai menjalankan /usr/bin/gawk -f letter-freq.awk
sebagai gantinya.
Saya dapat menguji skrip dengan beberapa input sederhana. Misalnya, jika saya memasukkan alfabet ke dalam gawk
. saya skrip, setiap huruf harus memiliki frekuensi relatif 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
Mengulangi contoh itu tetapi menambahkan contoh tambahan dari huruf e akan mencetak huruf e dengan frekuensi relatif 2 dan setiap huruf lainnya sebagai 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
Dan sekarang saya dapat mengambil langkah besar! Saya akan menggunakan grep
perintah dengan /usr/share/dict/words
arsipkan dan identifikasi frekuensi huruf untuk semua kata yang dieja seluruhnya dengan huruf kecil:
$ 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
Dari semua kata kecil di /usr/share/dict/words
file, huruf j , q , dan x paling jarang terjadi. Huruf z juga cukup langka. Tidak mengherankan, huruf e adalah yang paling sering digunakan.