引言
国家语言文字工作委员会和国家教育委员会于1988年1月26日发布了《现代汉语常用字表》(共3500字,常用字2500字,次常用字1000字),是从1928年至1986年的丰富的样本中进行统计分析后得到的。山西大学计算机科学系利用计算机抽样统计二百万字的语料,检测选收的常用字的使用频率。检测结果是:常用字(2500字)覆盖率达 97.97%,次常用字(1000字)覆盖率达 1.51%,合计(3500字)覆盖率达 99.48%,其他汉字只占 0.52%。
我从网络上找了下面四份有代表性中文文本资料进行统计分析:
- 《鲁迅文集》,鲁迅是中国现代伟大的文学家。他的作品我基本上只在课本中读过。
- 《金庸全集》,金庸的十五部武侠小说我都非常喜欢。
- 《路遥全集》,路遥的《人生》和《平凡的世界》是我最喜欢的小说。
- 《楚天碧心》,网络写手“雪鸿”发表于起点中文网站的玄幻小说。
四份中文文本资料的统计结果
下面就是这四份中文文本资料总的统计结果的第一部分:
A: 14,830,693 96.72% | 2,499 35.18% | 5934.65 B: 319,147 2.08% | 992 13.96% | 321.72 C: 184,152 1.20% | 3,613 50.86% | 50.97 T: 15,333,992 100.00% | 7,104 100.00% | 2158.50 (A:1) 涝 (B:8) 泵蓖玖柠柒檩蟥癣
从上述结果可以看出,在这四份中文文本资料中:
- T: 合计数 总共有一千五百多万字,其中只有七千多个不同汉字。每个(不同的)汉字平均出现 2,158.50 次。
- A: 常用字 有 2,499 个不同的常用字,每个常用字平均出现 5,934.65 次,共有一千四百八十多万字,占比为 96.72%。
- B: 次常用字 有 992 个不同的次常用字,每个次常用字平均出现 321.72 次,共有三十多万字,占比为 2.08%。
- C: 其他汉字 有 3,613 个不同的其他汉字,每个其他汉字平均出现 50.97 次,共有十八万多字,占比为 1.20%。
- 现代汉语常用字总共 2,500 个,上述统计资料中已经出现 2,499 个,只有一个没有出现,这个字是“涝”。
- 现代汉语次常用字总共 1,000 个,上述统计资料中已经出现 992 个,有八个没有出现,它们是:泵蓖玖柠柒檩蟥癣。
下面是统计结果的第二部分节选:
A: 420,880 [的] 2.74% 2.74% 1 A: 282,859 [一] 1.84% 4.59% 2 A: 270,379 [不] 1.76% 6.35% 3 A: 258,535 [是] 1.69% 8.04% 4 A: 242,943 [了] 1.58% 9.62% 5 A: 177,341 [他] 1.16% 10.78% 6 A: 168,136 [这] 1.10% 11.88% 7 A: 166,771 [人] 1.09% 12.96% 8 A: 146,256 [道] 0.95% 13.92% 9 A: 136,026 [我] 0.89% 14.80% 10 A: 133,268 [在] 0.87% 15.67% 11 A: 122,918 [来] 0.80% 16.48% 12 A: 122,706 [有] 0.80% 17.28% 13 A: 110,303 [大] 0.72% 17.99% 14 A: 107,686 [你] 0.70% 18.70% 15 A: 107,011 [之] 0.70% 19.39% 16 A: 95,034 [上] 0.62% 20.01% 17 A: 89,860 [说] 0.59% 20.60% 18 A: 89,294 [中] 0.58% 21.18% 19 A: 81,480 [个] 0.53% 21.71% 20 ... A: 11,693 [八] 0.08% 64.71% 266 C: 11,642 [韦] 0.08% 64.78% 267 A: 11,629 [未] 0.08% 64.86% 268 A: 11,466 [石] 0.07% 64.94% 269 ... A: 9,701 [完] 0.06% 68.16% 316 A: 9,694 [军] 0.06% 68.22% 317 B: 9,678 [郭] 0.06% 68.29% 318 A: 9,663 [奇] 0.06% 68.35% 319 ... C: 1 [隣] 0.00% 100.00% 7,104 End
上面是样本中出现的 7,104 个不同汉字按出现的次数降序排列的结果。从中可以看出,在这四份中文文本资料中:
- 最常用字是“的”字,出现了四十多万次,占比为 2.74%。
- 前十个常用字占比超过百分之十四,前二十个常用字占比超过百分之二十一。注意,样本中总共有七千多个不同的字。
- 占前 266 位的都是常用字。第 267 位是“韦”字(其他汉字),占比为 0.08%,这是《鹿鼎记》中主角韦小宝的姓。
- 次常用字第一次出现于第 318 位,是“郭”字,占比为 0.06%,这是《射雕英雄传》中主角郭靖的姓。
《鲁迅文集》的统计结果
下面是《鲁迅文集》统计结果的第一部分:
A: 2,090,716 95.80% | 2,486 37.99% | 841.00 B: 51,546 2.36% | 947 14.47% | 54.43 C: 40,226 1.84% | 3,111 47.54% | 12.93 T: 2,182,488 100.00% | 6,544 100.00% | 333.51 (A:14) 雹蹦踩叼盯秆饺挎涝眯乓膨馅氧 (B:53) 泵蓖膘憋茬碴搓掸矾钙埂焊夯秸玖抠晾铝峦锚铆锰蘑蔫撵镊柠啤柒呛瓤苫酥檩捅蟥豌捂嘀馍芯癣堰掰椰涮笤啰麸咪衩杈籽
从上述结果可以看出,在《鲁迅文集》中:
- 总共有二百多万字,其中只有六千五百多个不同汉字。每个(不同的)汉字平均出现 333.51 次。
- 有 2,486 个不同的常用字,每个常用字平均出现 841.00 次,共有二百多万字,占比为 95.80%。
- 有 947 个不同的次常用字,每个次常用字平均出现 54.43 次,共有五万多字,占比为 2.36%。
- 有 3,111 个不同的其他汉字,每个其他汉字平均出现 12.93 次,共有四万多字,占比为 1.84%。
- 没有出现的常用字有十四个,次常用字有五十三个。
下面是统计结果的第二部分节选:
A: 77,953 [的] 3.57% 3.57% 1 A: 39,195 [一] 1.80% 5.37% 2 A: 32,135 [是] 1.47% 6.84% 3 A: 28,184 [不] 1.29% 8.13% 4 A: 23,931 [人] 1.10% 9.23% 5 A: 23,449 [有] 1.07% 10.30% 6 A: 20,081 [了] 0.92% 11.22% 7 A: 17,853 [之] 0.82% 12.04% 8 A: 17,844 [在] 0.82% 12.86% 9 A: 16,121 [我] 0.74% 13.60% 10 A: 15,977 [为] 0.73% 14.33% 11 A: 15,046 [文] 0.69% 15.02% 12 A: 14,443 [这] 0.66% 15.68% 13 A: 14,279 [也] 0.65% 16.33% 14 A: 14,008 [以] 0.64% 16.98% 15 A: 13,616 [于] 0.62% 17.60% 16 A: 13,358 [他] 0.61% 18.21% 17 A: 13,054 [年] 0.60% 18.81% 18 A: 12,966 [中] 0.59% 19.40% 19 A: 12,885 [说] 0.59% 19.99% 20 ... A: 1,933 [高] 0.09% 62.10% 240 C: 1,921 [曰] 0.09% 62.19% 241 B: 1,915 [谓] 0.09% 62.28% 242 A: 1,909 [迅] 0.09% 62.36% 243 ... C: 1 [隣] 0.00% 100.00% 6,544 End
上面是《鲁迅文集》中出现的 6,544 个不同汉字按出现的次数降序排列的结果。从中可以看出,在《鲁迅文集》中:
- 最常用字是“的”字,占比为 3.57%。
- 前十个常用字占比超过百分之十三,前十二个常用字占比极为接近百分之二十。
- 占前 240 位的都是常用字。第 241 位是“曰”字(其他汉字),占比为 0.09%,这个字在现代汉语中很少用,但在文言文中很常用。
- 次常用字第一次出现于第 242 位,是“谓”字,占比为 0.09%。
《金庸全集》的统计结果
下面是《金庸全集》统计结果的第一部分:
A: 7,017,673 96.12% | 2,495 46.67% | 2812.69 B: 185,331 2.54% | 918 17.17% | 201.89 C: 97,913 1.34% | 1,933 36.16% | 50.65 T: 7,300,917 100.00% | 5,346 100.00% | 1365.68 (A:5) 菠吨阀涝秒 (B:82) 癌氨泵蓖蹭茬碴椿氮碘淀囤哆肪啡钙柑埂硅夯荚钾秸玖咖抠榔晾馏铝氯铆檬锰钠蔫柠硼啤浦柒氢瘸瓤叁苫赡黍栓檩碳誊蟥蜕鲫捂嘁榛锨腺锌癣汛蚜胰肄笤蛉荧蛹麸秫芋荸酝荞茴衩蔗杈蛀籽
从上述结果可以看出,在《金庸全集》中:
- 总共有七百三十万多字,其中只有五千三百多个不同汉字。每个(不同的)汉字平均出现 1,365.68 次。
- 有 2,495 个不同的常用字,每个常用字平均出现 2,812.69 次,共有七百多万字,占比为 96.12%。
- 有 918 个不同的次常用字,每个次常用字平均出现 201.89 次,共有十八万多字,占比为 2.54%。
- 有 1,933 个不同的其他汉字,每个其他汉字平均出现 50.65 次,共有九万多字,占比为 1.34%。
- 没有出现的常用字有五个,它们是:菠吨阀涝秒。“吨”和“秒”这两个常用字没有出现很奇怪,看来武侠小说中的重量单位和时间单位有所不同。
- 没有出现的次常用字有八十二个。
下面是统计结果的第二部分节选:
A: 140,297 [一] 1.92% 1.92% 1 A: 134,824 [不] 1.85% 3.77% 2 A: 122,715 [的] 1.68% 5.45% 3 A: 113,314 [是] 1.55% 7.00% 4 A: 112,686 [了] 1.54% 8.54% 5 A: 111,634 [道] 1.53% 10.07% 6 A: 85,002 [人] 1.16% 11.24% 7 A: 73,912 [他] 1.01% 12.25% 8 A: 69,313 [这] 0.95% 13.20% 9 A: 67,293 [我] 0.92% 14.12% 10 A: 64,498 [来] 0.88% 15.00% 11 A: 61,859 [你] 0.85% 15.85% 12 A: 60,094 [大] 0.82% 16.68% 13 A: 52,611 [在] 0.72% 17.40% 14 A: 51,003 [上] 0.70% 18.09% 15 A: 48,897 [中] 0.67% 18.76% 16 A: 48,494 [得] 0.66% 19.43% 17 A: 48,487 [之] 0.66% 20.09% 18 A: 48,071 [说] 0.66% 20.75% 19 A: 45,481 [下] 0.62% 21.37% 20 ... A: 11,486 [日] 0.16% 49.08% 121 A: 11,373 [走] 0.16% 49.24% 122 C: 11,349 [韦] 0.16% 49.39% 123 A: 11,226 [四] 0.15% 49.55% 124 ... A: 9,457 [白] 0.13% 54.67% 161 B: 9,406 [郭] 0.13% 54.80% 162 A: 9,373 [众] 0.13% 54.93% 163 A: 9,293 [方] 0.13% 55.06% 164 ... C: 1 [龂] 0.00% 100.00% 5,346 End
上面是《金庸全集》中出现的 5,346 个不同汉字按出现的次数降序排列的结果。从中可以看出,在《金庸全集》中:
- 最常用字是“一”字,占比为 1.92%。“的”字降到第三位,占比为 1.68%。
- 前十个常用字占比超过百分之十四,前二十个常用字占比超过百分之二十一。
- 占前 122 位的都是常用字。第 123 位是“韦”字(其他汉字),占比为 0.16%,这是《鹿鼎记》中主角韦小宝的姓。
- 次常用字第一次出现于第 162 位,是“郭”字,占比为 0.13%,这是《射雕英雄传》中主角郭靖的姓。
《路遥全集》的统计结果
下面是《路遥全集》统计结果的第一部分:
A: 1,310,090 98.28% | 2,476 61.82% | 529.12 B: 16,660 1.25% | 807 20.15% | 20.64 C: 6,286 0.47% | 722 18.03% | 8.71 T: 1,333,036 100.00% | 4,005 100.00% | 332.84 (A:24) 菠钞阀冈蕉晋鞠姥涝滤箩券删沈肾艘艇沃虾佣轧浙脂粥 (B:193) 氨捌蚌焙泵蓖舶渤埠雌崔掸氮缔佃碉谍锭痘兑讹贰筏樊肪枫孵柑肛篙镐羹埂刽亥翰夯沪淮涣宦蝗幌畸妓钾剿酵芥鲸靖玖臼炬骏拷傀莱缆榔酪儡荔吏痢磷菱琉馏卤仑铆檬锰皿闽螟募钠馁镊柠疟鸥潘胚烹彭篷圃柒黔擎蛆蓉叁苫擅赡芍赊恃蜀黍璧鳍鳄髓蟀蟋瞭檩檀谭棠誊鹦螃蹂彤蟥臀鸵薇宛鲫纬蝙蜗蝠诬坞箫嘁榕榛犀铣腺湘淆蟹锌蜈邢楣旭轩癣鹉衙砚鸯牍锉椰掖胰邑肄笙淫啰蛉荧蛹秫蚣桦荸祠鸳袁粤陨秕蚤斋荠樟账玷昙蔗茉疹鸠芙阱凫椎滓匕
从上述结果可以看出,在《路遥全集》中:
- 总共有一百三十多万字,其中只有四千多个不同汉字。每个(不同的)汉字平均出现 332.84 次。
- 有 2,476 个不同的常用字,每个常用字平均出现 529.12 次,共有一百三十多万字,占比为 98.28%。
- 有 807 个不同的次常用字,每个次常用字平均出现 20.64 次,共有一万六千多字,占比为 1.25%。
- 有 722 个不同的其他汉字,每个其他汉字平均出现 8.71 次,共有六千多字,占比为 0.47%。
- 没有出现的常用字有二十四个,次常用字有一百九十三个。
下面是统计结果的第二部分节选:
A: 53,403 [的] 4.01% 4.01% 1 A: 29,519 [一] 2.21% 6.22% 2 A: 26,198 [了] 1.97% 8.19% 3 A: 24,465 [他] 1.84% 10.02% 4 A: 19,876 [不] 1.49% 11.51% 5 A: 18,160 [在] 1.36% 12.87% 6 A: 17,023 [是] 1.28% 14.15% 7 A: 16,881 [这] 1.27% 15.42% 8 A: 14,123 [人] 1.06% 16.48% 9 A: 13,807 [我] 1.04% 17.51% 10 A: 12,996 [个] 0.97% 18.49% 11 A: 12,393 [上] 0.93% 19.42% 12 A: 11,904 [来] 0.89% 20.31% 13 A: 11,072 [地] 0.83% 21.14% 14 A: 9,975 [有] 0.75% 21.89% 15 A: 9,506 [说] 0.71% 22.60% 16 A: 9,383 [里] 0.70% 23.31% 17 A: 9,087 [着] 0.68% 23.99% 18 A: 8,740 [就] 0.66% 24.64% 19 A: 8,728 [她] 0.65% 25.30% 20 ... A: 1,188 [应] 0.09% 65.08% 216 A: 1,181 [并] 0.09% 65.17% 217 B: 1,177 [哩] 0.09% 65.26% 218 A: 1,173 [块] 0.09% 65.34% 219 ... A: 507 [期] 0.04% 80.29% 476 C: 506 [圪] 0.04% 80.33% 477 A: 504 [室] 0.04% 80.37% 478 A: 503 [虽] 0.04% 80.40% 479 ... C: 1 [龋] 0.00% 100.00% 4,005 End
上面是《路遥全集》中出现的 4,005 个不同汉字按出现的次数降序排列的结果。从中可以看出,在《路遥全集》中:
- 最常用字是“的”字,占比为 4.01%。
- 前十个常用字占比超过百分之十七,前二十个常用字占比超过百分之二十五。
- 占前 217 位的都是常用字。第 218 位是“哩”字(次常用字),占比为 0.09%。
- 其他汉字第一次出现于第 477 位,是“圪”字,占比为 0.04%。
《楚天碧心》的统计结果
下面中《楚天碧心》统计结果的第一部分:
A: 4,412,214 97.67% | 2,454 57.16% | 1797.97 B: 65,610 1.45% | 824 19.19% | 79.62 C: 39,727 0.88% | 1,015 23.64% | 39.14 T: 4,517,551 100.00% | 4,293 100.00% | 1052.31 (A:46) 袄柏菠锻缎纺溉秆鸽桂贿舰椒饺刊糠炕挎筐葵涝粱萝箩骡馒纽锹侨芹陕肾蔬穗痰倘袜锡宪橡秧氧咏枣橘蜻 (B:176) 癌氨澳捌苞焙泵蓖膘舶渤埠豺橱矗椿囱崔氮碘佃淀碉锭墩囤垛贰筏樊矾肪啡钙柑篙镐蛤汞硅亥焊杭沪淮宦蛔荚钾碱秸玖韭鹃莱缆荔痢哩潦馏瘤赂铝氯玛锚檬娩闽摹牡钠捻聂镊柠疟糯鸥帕硼譬圃浦柒畦黔瘸瓤纫赡芍绅黍栓蟀檩碳棠誊屉鹦蟆蟥鸵薇豌嬉桅苇嘹橄坞箫幔嘁榕榛铣锨舷腺馍芯锌邢匈楣酗癣榄蒿汛鹉蚜堰唁腌谚牍跛姚椰壹胰庵邑肄笤笙铐蛉麸秫唧桦荸袁耘秕蚤荠荞樟茴玷衩蔗茉疹怔姊蛀凫籽
从上述结果可以看出,在《楚天碧心》中:
- 总共有四百五十多万字,其中只有四千多个不同汉字。每个(不同的)汉字平均出现 1,052.31 次。
- 有 2,454 个不同的常用字,每个常用字平均出现 1,797.97 次,共有四百四十多万字,占比为 97.67%。
- 有 824 个不同的次常用字,每个次常用字平均出现 79.62 次,共有六万五千多字,占比为 1.45%。
- 有 1,015 个不同的其他汉字,每个其他汉字平均出现 39.14 次,共有三万九千多字,占比为 0.88%。
- 没有出现的常用字有四十六个,次常用字有一百七十六个。
下面是统计结果的第二部分节选:
A: 166,809 [的] 3.69% 3.69% 1 A: 96,063 [是] 2.13% 5.82% 2 A: 87,495 [不] 1.94% 7.76% 3 A: 83,978 [了] 1.86% 9.61% 4 A: 73,848 [一] 1.63% 11.25% 5 A: 67,499 [这] 1.49% 12.74% 6 A: 65,606 [他] 1.45% 14.20% 7 A: 46,618 [有] 1.03% 15.23% 8 A: 44,653 [在] 0.99% 16.22% 9 A: 43,715 [人] 0.97% 17.18% 10 A: 40,299 [雪] 0.89% 18.08% 11 A: 40,023 [鹰] 0.89% 18.96% 12 A: 39,194 [之] 0.87% 19.83% 13 A: 38,805 [我] 0.86% 20.69% 14 A: 35,761 [你] 0.79% 21.48% 15 A: 35,165 [们] 0.78% 22.26% 16 A: 35,142 [天] 0.78% 23.04% 17 A: 35,135 [来] 0.78% 23.81% 18 A: 31,036 [大] 0.69% 24.50% 19 A: 30,506 [个] 0.68% 25.18% 20 ... A: 5,780 [却] 0.13% 61.85% 156 A: 5,762 [重] 0.13% 61.98% 157 C: 5,759 [冥] 0.13% 62.11% 158 A: 5,656 [正] 0.13% 62.23% 159 ... A: 2,889 [甲] 0.06% 75.28% 307 A: 2,885 [未] 0.06% 75.34% 308 B: 2,883 [幽] 0.06% 75.41% 309 A: 2,882 [佛] 0.06% 75.47% 310 ... C: 1 [龉] 0.00% 100.00% 4,293 End
上面是《楚天碧心》中出现的 4,293 个不同汉字按出现的次数降序排列的结果。从中可以看出,在《楚天碧心》中:
- 最常用字是“的”字,占比为 3.69%。
- 前十个常用字占比超过百分之十七,前二十个常用字占比超过百分之二十五。
- 占前 157 位的都是常用字。第 158 位是“冥”字(其他汉字),占比为 0.13%。
- 次常用字第一次出现于第 309 位,是“幽”字,占比为 0.06%。
用于统计的 C# 源程序
下面就是相应的 C# 源程序 ChineseCounter.cs:
1 using System; 2 using System.IO; 3 using System.Collections.Generic; 4 5 namespace Skyiv.Utils 6 { 7 // 对中文文本进行统计分析,主要统计其中常用字和次常用字的占比。 8 sealed class ChineseCounter 9 { 10 static readonly string Skiped = 11 "" + 12 " 、,。.·?!:;…-─~—_|丨Ⅰ∶※★●℃°“”‘’《》[]〔〕()<>〈〉【】〖〗□" + 13 "㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩①②③④⑤⑥⑦⑧⑨⑩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇" + 14 "ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒚⒛" + 15 "1234567890=+-×÷/%ⅢⅡ≈⊥′āáǎàéěèōóǒü" + // ○ 16 " 1234567890=+-*/%{}[]()<>?!@#$^&_:;',.`~|\"\\" + 17 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 18 "abcdefghijklmnopqrstuvwxyz" + 19 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 20 static readonly string Group = "ABCT"; // A:常用字 B:次常用字 C:其他 T:合计 21 static readonly HashSet<char> A, B; // A:常用字(2500字) B:次常用字(1000字) 22 23 Dictionary<char, int> charCount = new Dictionary<char, int>(); 24 25 static ChineseCounter() 26 { 27 A = new HashSet<char>(new RandomChinese(RandomChinese.Source.From2500).GetSource()); 28 B = new HashSet<char>(new RandomChinese(RandomChinese.Source.From3500).GetSource()); 29 B.ExceptWith(A); // 次常用字(1000字) = 现代汉语常用字(3500字) - 常用字(2500字) 30 } 31 32 // 读取中文文本的内容,计算每个汉字出现的次数 33 void Read(string fileName) 34 { 35 foreach (var line in File.ReadLines(fileName)) 36 foreach (var c in line) 37 { 38 int count; 39 charCount.TryGetValue(c, out count); 40 charCount[c] = count + 1; 41 } 42 } 43 44 // 计算统计资料中常用字和次常用字出现的次数 45 int[,] GetGroups() 46 { 47 var groups = new int[4, 2]; // 0:常用字 1:次常用字 2:其他 3:合计, 0:Distinct 1:Count 48 foreach (var kvp in charCount) 49 { 50 var k = GetGroupIndex(kvp.Key); 51 groups[k, 0]++; 52 groups[3, 0]++; 53 groups[k, 1] += kvp.Value; 54 groups[3, 1] += kvp.Value; 55 } 56 return groups; 57 } 58 59 // 将统计资料中的汉字按其出现的次数降序排序 60 Tuple<int, char>[] GetItems() 61 { 62 var items = new Tuple<int, char>[charCount.Count]; // Item1:count Item2:char 63 var i = 0; 64 foreach (var kvp in charCount) items[i++] = Tuple.Create(-kvp.Value, kvp.Key); 65 Array.Sort(items); 66 return items; 67 } 68 69 // 报告统计资料中常用字和次常用字的占比等分析数据 70 void Report(int[,] groups) 71 { 72 for (var i = 0; i < groups.GetLength(0); i++) 73 Console.WriteLine("{5}: {0,10:N0} {1,7:P} | {2,5:N0} {3,7:P} | {4,7:F2}", 74 groups[i, 1], groups[i, 1] / (double)groups[3, 1], 75 groups[i, 0], groups[i, 0] / (double)groups[3, 0], 76 groups[i, 1] / (double)groups[i, 0], Group[i]); 77 Console.WriteLine(); 78 } 79 80 // 报告没有在统计资料中出现的常用字和次常用字 81 void Report(HashSet<char> set, int idx) 82 { 83 var set2 = new HashSet<char>(set); 84 set2.ExceptWith(charCount.Keys); 85 Console.Write("({0}:{1}) ", Group[idx], set2.Count); 86 foreach (var c in set2) Console.Write(c); 87 Console.WriteLine(); 88 } 89 90 // 报告统计资料中每个的汉字的出现次数(降序)及占比 91 void Report(Tuple<int, char>[] items, double total) 92 { 93 Console.WriteLine(); 94 for (int sum = 0, i = 0; i < items.Length; i++) 95 Console.WriteLine("{0}: {1,7:N0} [{2}] {3,6:P} {4,7:P} {5,5:N0}", 96 Group[GetGroupIndex(items[i].Item2)], -items[i].Item1, items[i].Item2, 97 -items[i].Item1 / total, (sum += -items[i].Item1) / total, i + 1); 98 Console.WriteLine("End"); 99 } 100 101 // 将汉字分配到以下三组中: 0:常用字 1:次常用字 2:其他汉字 102 int GetGroupIndex(char c) 103 { 104 return (A.Contains(c)) ? 0 : (B.Contains(c)) ? 1 : 2; 105 } 106 107 void Run(string[] fileNames) 108 { 109 foreach (var fileName in fileNames) Read(fileName); 110 foreach (var c in Skiped) charCount.Remove(c); 111 var groups = GetGroups(); 112 Report(groups); // 报告统计资料中常用字和次常用字的占比 113 Report(A, 0); // 报告没有在统计资料中出现的常用字 114 Report(B, 1); // 报告没有在统计资料中出现的次常用字 115 Report(GetItems(), groups[3, 1]); // groups[3, 1]: 总字数 116 } 117 118 static void Main(string[] args) 119 { 120 new ChineseCounter().Run(args); 121 } 122 } 123 }
上述程序中已经有了适当的注释,现简要分析如下:
- 第10至19行定义的静态只读字符串 Skiped 用于排除统计资料中的非汉字字符。要注意的是,由于是从网络中获取数据,质量不是很好,文本中有些乱码,会造成一定的干扰。有些干扰可以通过 Skiped 排除。
- 第25至30行的静态构造函数初始化 2500 个常用字和 1000 个次常用字到相应的集合中,以供后面统计分析使用。
- 第32至42行的 Read 方法从中文文本中读取数据。可以在命令行指定多个文本文件,一并读取。文本文件必须使用 UTF-8 编码。
- 第107至116行的 Run 方法总控程序的运行,依次读取数据、排除非汉字字符、进行统计分析、报告统计结果。
编译和运行
在 Arch Linux 的 Mono 2.10.8 环境下编译和运行:
work$ dmcs ChineseCounter.cs RandomChinese.cs work$ mono ChineseCounter.exe *.txt work$ mono ChineseCounter.exe 鲁迅文集.txt work$ mono ChineseCounter.exe 金庸全集.txt work$ mono ChineseCounter.exe 路遥全集.txt work$ mono ChineseCounter.exe 楚天碧心.txt
说明如下:
- 编译时需要用到 RandomChinese.cs 来提供常用字和次常用字,请参见:随机生成常用汉字(再次改进版)。
- 第一次运行的命令行参数是 *.txt,用于生成全部资料的统计结果。如果在 Windows 下运行,需要在命令行上依次给出四个文件名。
- 后四次运行依次生成相应的统计结果。
- 实际运行时可将结果重定向到文件中。
参考资料