<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
編寫一個 awk 指令碼來找到一組單詞中出現次數最多(和最少)的單詞。
近一段時間,我開始編寫一個小遊戲,在這個小遊戲裡,玩家使用一個個字母塊來組成單詞。編寫這個遊戲之前,我需要先知道常見英文單詞中每個字母的使用頻率,這樣一來,我就可以找到一組更有用的字母塊。字母頻次統計在很多地方都有相關討論,包括在 維基百科 上,但我還是想要自己來實現。
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
沒錯,這些都是合法的單詞。比如,“aahed” 是 “aah” 的過去式,表示在放鬆時的感嘆,而 “aalii” 是一種濃密的熱帶灌木。
現在我只需要編寫一個 gawk 指令碼來統計出單詞中各個字母出現的次數,然後列印出每個字母的相對頻率。
一種使用 gawk 來統計字母個數的方式是,遍歷每行輸入中的每一個字元,然後對 “a” 到 “z” 之間的每個字母進行計數。substr 函數會返回一個給定長度的子串,它可以只包含一個字元,也可以是更長的字串。比如,下面的範例程式碼能夠取到輸入中的每一個字元 c:
{ len = length($0); for (i = 1; i <= len; i++) { c = substr($0, i, 1); } }
如果使用一個全域性字串變數 LETTERS 來儲存字母表,我就可以藉助 index 函數來找到某個字元在字母表中的位置。我將擴充套件 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 的陣列,我就可以利用這個陣列來統計每個字母出現的次數。我將在下面的範例程式碼中新增這個功能,每當一個字母出現在輸入中,我就讓它對應的陣列元素值增加 1(使用 ++):
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 指令碼統計完所有的字母后,我希望它能輸出每個字母的頻率。畢竟,我對輸入中各個字母的個數沒有興趣,我更關心它們的 相對頻率。
我將先統計字母 “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.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 # 只統計 a-z 的字元,忽略 A-Z 和其他的字元 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]; } } } # 列印每個字元的相對頻率 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。如此一來,當你在 shell 中執行 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:
$ 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” 是使用頻率最高的。
via: https://opensource.com/article/21/4/gawk-letter-game
以上就是awk指令碼統計一組單詞中字母出現最多最少頻率的詳細內容,更多關於awk指令碼統計字母頻率的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45