引言
我在两个月前写了一篇随笔“随机生成常用汉字”,生成汉字的来源是国标(GB2312)一级字(共3755字)。园友 Aimeast 在评论中说:
并不是一级汉字中的汉字就是常用的。最好的办法是从丰富的样本中进行统计分析后得出哪些是常用汉字。
正好,国家语言文字工作委员会和国家教育委员会于1988年1月26日发布了《现代汉语常用字表》,共3500字,是从1928年至1986年的丰富的样本中进行统计分析后得到的。
我在这个月中旬写了一篇随笔“现代汉语常用字与国标一级的比较”。经比较发现,现代汉语常用字中有126字是国标一级字中没有的,国标一级字中有381字是现代汉语常用字中没的。
随机生成常用汉字的 C# 程序(改进版)
根据上述讨论,就很容易写出从现代汉语常用字中随机生成汉字的程序,如下所示:
1 using System; 2 using System.Text; 3 using System.Linq; 4 using System.Collections.Generic; 5 6 namespace Skyiv.Utils 7 { 8 static class ChineseCreator 9 { 10 static void Main(string[] args) 11 { 12 var count = (args.Length > 0) ? int.Parse(args[0]) : 1800; 13 var isGB2312 = args.Length > 1 && args[1] == "from3755"; 14 var str = isGB2312 ? GetGB2312String() : GetChineseString(); 15 var random = new Random(); 16 var sb = new StringBuilder(count); 17 for (var len = str.Length; count > 0; count--) 18 sb.Append(str[random.Next(len)]); 19 Console.WriteLine(sb); 20 } 21 22 // 现代汉语常用字(共3500个) 23 static string GetChineseString() 24 { 25 var set = new HashSet<char>(GetGB2312String()); 26 set.ExceptWith("皑胺盎敖翱佰稗镑鲍钡苯甭迸毖敝陛卞斌摈炳钵铂箔帛蔡搽诧谗掣郴骋炽踌瞅躇滁" + 27 "搐椽疵茨蹿瘁淬磋傣殆郸惮迪狄翟滇靛凋迭侗恫犊遁掇剁峨娥厄鄂洱珐藩钒酚汾烽氟涪弗釜腑阜讣噶" + 28 "嘎赣皋铬庚龚蛊剐圭癸辊骸氦邯郝菏貉阂涸亨弘瑚桓豢磺簧卉烩姬缉汲蓟伎悸笺缄硷槛饯铰桔睫藉疥" + 29 "靳烬粳痉炯厩咎狙疽咀踞娟撅攫抉浚郡喀咯亢柯侩匡岿奎馈婪阑谰佬镭磊傈涟撂廖霖拎羚陇掳麓潞禄" + 30 "戮挛孪滦纶嘛谩卯酶镁寐醚幂抿牟氖淖妮霓倪拈啮镍涅哦沤啪琶磐耪呸裴抨砒琵毗痞瞥粕莆埔曝沏祁" + 31 "讫扦钎仟堑羌蔷橇鞘沁氰邱酋泅龋颧醛炔榷冉壬妊戎茹孺汝阮鳃莎煽汕缮墒韶邵慑砷娠噬仕孰戍舜朔" + 32 "嗣巳怂擞僳隋绥蓑獭挞酞坍绦锑嚏腆迢眺烃汀酮湍陀哇烷皖韦惟潍渭挝斡钨吾毋戊硒矽嘻烯汐檄襄霄" + 33 "忻惺墟戌嘘眩绚丫焉阉彦佯疡瑶尧噎耶曳铱颐沂彝矣臆裔诣翌荫寅尹臃痈雍恿铀酉釉盂虞俞渝禹峪驭" + 34 "垣苑曰郧匝哉札咋詹辗湛漳瘴肇蛰锗甄砧臻帧峙炙痔诌诛瞩拽篆兹淄孜渍鬃邹纂佐柞"); 35 set.UnionWith("叨蜓筝蜻橘匕丐夭叽吆凫阱芙杈岖鸠沐姊卦拗茉昙肴衩玷茴荞荠盹咧昵咪秕胧奕飒炫" + 36 "祠荸莺桦唠蚣蚪蚓唧秫麸捺匾蚯蛉啰铐铛笙笤偎徙翎庵涮悴裆谒雳跛锉掰牍腌猬愕鹉蒿榄楣嗦跷蜈嗤" + 37 "馍禀缤榛榕嘁嘀幔箫漩橄嘹蝠蝌蝙鲫憔翩嬉缭薇噩蟥霎踱蹂蟆螃鹦瘾缰檐檩瞭蟋蟀朦臊鳄鳍癞璧簸鬓躏"); 38 return new string(set.ToArray()); 39 } 40 41 // 国标一级字(共3755个): 区:16-55, 位:01-94, 55区最后5位为空位 42 static string GetGB2312String() 43 { 44 var list = new List<byte>(); 45 for (var 区 = 16; 区 <= 55; 区++) 46 for (int 位2 = (区 == 55) ? 89 : 94, 位 = 1; 位 <= 位2; 位++) 47 { 48 list.Add((byte)(区 + 0xa0)); 49 list.Add((byte)(位 + 0xa0)); 50 } 51 return Encoding.GetEncoding("GB2312").GetString(list.ToArray()); 52 } 53 } 54 }
上述程序中:
- 第41到52行的 GetGB2312String 方法生成3755个国标一级字。
- 第22到39行的 GetChineseString 方法生成3500个现代汉语常用字。该方法首先生成3755国标一级字,然后排除381个汉字,接着增加126个汉字。
- 第12行:该程序的第一个命令行参数(如果有的话)表示需要生成的汉字个数,默认是1800个。
- 第13行:该程序的第二个命令行参数(如果有的话)表示所生成的汉字的来源,默认是现代汉语常用字。
编译和运行
在 Arch Linux 和 Mono 2.10.8 环境下编译和运行:
work$ uname -a Linux s4700 3.6.10-1-ARCH #1 SMP PREEMPT Tue Dec 11 09:40:17 CET 2012 x86_64 GNU/Linux work$ dmcs --version Mono C# compiler version 2.10.8.0 work$ dmcs ChineseCreator.cs work$ mono ChineseCreator.exe 500 抖煞鼻缓官机俯撰拒阳导伟惨胆票溜求婆初溃狱刺嗽澎庙梧旱瘟剧曙辱萧判行贞过库蔑琼裹震诱然瀑脆吹仲滩袱鸡疾川使藏特看迟馆杰棕载涂累窜誉喊斗疟捌瘤美欲究兄崇谢米搔焰摧饲罢历砍未又胯莉运腾冲饮猛殿闲勃屁馍码桨胜绢移趁诗晦塘虎娇悬浊蟀酵柿源表海鸿禁椰偷砍彩唐嗦聪辩湖翻叙戳岗蛔梆蹈琢谈显媒套饰怠柴操桌瓦楣巷介松懊花陕舒葛辆扯衍指叔蠕枣刑施凡音苫胡漱泛瑰茫毡笋鸯陆物粒密魁备搁拣配胳扶吏竖夜候刻谅担迹瞒访辅拦古萍株懒稼症史心掷承馏磅疤鳞拙趟坏泛谐捏阀组速跟庇篡缸遥杜撰辩必摩溯庄骆恳桑故射何币酪越庙疑溶锻筐扒诚哨苞梗疚讽卜祭敛宜青贝切金燕榔深赐拯灯除村写橡聊岂阱沦吟壹餐秕裂纪梨把萌洞痒全堰虎水储咆电含少妙斩游爹激片蜘防幅驮旋晋屯钥茫验榜假渴蒙旋涛陡俺圣绊毫植牙嘿雁憨决好势陪悼妒率忍悔穿饰座襟盯凌淹侍事叶琴溅籽嚣规巧狮捏细狸泄亡三陋突涕臀瞧件泪袱嗽萎甚哈恳朵公辣洛身虑擦夷辟疟晰轩斋淹砾任登蜂痴令跃恳臭掀护色撼氛构诞洪碘蜗挖徐循拳珍筝钙蕊镰驹悔衅经蒙菩帝扰量企烙打村雹弥塑输锈铐措乙牍噪精满寿北茶贷染勃南跋韭驻专双过等囚拼梁宏蝶汇载虚贸捐斟暂战撑靶揩徙滑掠康牧语浴买舀搬赘役芙慰锹翼匪绿炸肝毡侮岳赚搔咳取替牲踢 work$ mono ChineseCreator.exe 500 from3755 振拐浦孩帧梗撇拂耿戏纠颅胜漱逆典吁燕酣福系氨酒甚液淖韶肢谭嘉赞硝豆结俘林少器蜜捉竿翅熊奏剂唁僻胯惕编洛哗盎析摸蝶辰隔玻氖敲椎谭罐崎恨墒示巨庶秦漠戴钙头沫尊鞘吊叹梁楞渊冯艇漳侈哉悟栈效追负匈夸毯帚确荷邪杨肿柜笆攘玻钧惺憋浦簿垛咙粹炭颧晰迂洋沂霍贝矿粕雪鳃夯赐渠舜当非刨呛省鹤粥夏萌逮度涪侧阅膳悟锹申姿毋窿曳胺前漱嗜傈视九介臣且舰噪蜡腋储旁霉掌般当渊嘲朗临包羞优多俘氢危憾趋咆依辱番镶吨镰棘披椿狈惑姿螟冯王屋瘟嘘棋腋创旺壮灯肖邪们栖烦诗磺稀行决泼葱壁煌沸孩娟臣呐骗狡蝴亚妄矩块椿放长甄翰晨谐邪估拨恳稗舅业是缸莽真依馒詹奥虏尔望澡树笔影蹄做瞬浇淡鹤虹涝侄淌疥膳稠哩桃奸救搔缴蝎雷渠消诣娠快隶窑震吮啄叔痒冲有累汇且审潘积峭递弟凌音档涤薪溪槛插停镜渔饼叠翘羚趟诸吮污狸浪胃面汁坠炎氛隔锈苹贸今姻羚贮邱鬼延兰古探汲豫镰说蹈灶揭却蟹紧唱五墙誓初作巳缎杆呕美誓密沈怯***天圆枷献杉颤挚掺搅淄耘昏勇掩末材雀剥醉巳炕项渴咙您占畴凌场沟者痉襟典笆遍屉肿宴板锻平恃郎容佑息紊翱琵曝斌乞揪赴局凭堕檄且经租供稼玄鲸沙馒耕认唤验班令达狡耕爆鬼杜君喳首蒙婴征弹惫监示酪柜哇构兔嫁跑羔回桓手汪内洋二芍扛成玫翰骨钮谣错二春酣钻浅牧信佬防者 work$
第一次运行从3500个现代汉语常用字中随机生成500个汉字。第二次运行从3755个国标一级字中随机生成500个汉字。看起来这两次运行差别不大,说不上哪次生成的汉字更常用些。因为现代汉语常用字和国标一级字的大部分都是相同的。国标一级字其实也是从丰富的样本中统计出来的常用字。