吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3332|回复: 1
收起左侧

[会员申请] 申请会员ID:DealiAxy

[复制链接]
吾爱游客  发表于 2017-5-19 22:04
1、申 请 I D:DealiAxy
2、个人邮箱:deali@live.com
3、原创技术文章:
入门程序猿一枚,目前主要做网站后端开发(PHP、C#、Python),机器学习方向。
下面附上一篇技术文章,更多技术文章请参见我的博客:http://blog.deali.cn

                欣赏唐人文墨以及诗词分析(二)代码实现                        Begin
继上次对唐诗三百首和全唐诗四万多首诗进行分析之后…

详细内容可以看看上次这篇文章,《以大数据眼光欣赏唐人文墨(一)》

这篇文章来讲讲具体的代码实现,本项目全部采用C#编写。软件介绍
首先为了做本次分析,我用C#写了一个Winform程序,名字很逗比,叫做“我爱读诗词——唐诗”。
软件和唐诗三百首数据文件打包下载:http://pan.baidu.com/s/1gftDKTd
全唐诗数据由于太大了需要下载的同学点这个:http://pan.baidu.com/s/1nv4WNNF
下面是软件截图:

启动直接写成控制台的,反正就是自己用而已,粗糙一点无所谓,能用就行。
唐诗三百首匹配界面截图:

这里是从源文件读取数据并整理出每一首诗的标题、作者、内容。
全唐诗的匹配的界面:

你问我为什么这个的背景是深色的,我也不知道(摊手,反正当时就这么设置了= =…
由于全唐诗太多了,要打开并分析出来需要很长时间,所以这里用了小容量样本。
分析界面:

这个就是上次的文章里展示的,主要功能都在这里了。窗口主体是一个listview控件,用来分类显示分析结果。代码
关于从源文件整理出标题、作者、内容的代码,请参见  用C#学习唐诗三百首和全唐诗标题分析
首先是从数据文件里读取出每一首诗QData qD = new QData(poemFile);
定义一个 Dictionary<string, int> 结构,索引是标题,值是数量。
分析很简单,从QData对象读取出所有的标题然后判断是否在 Dictionary<string, int> 存在这个标题,如果存在数量就+1,如果不存在就添加进去。
代码如下:string[] sections = qD.GetAllSectionsArray();Console.WriteLine("共有[{0}]首诗", sections.Length);foreach (string s in sections){    Application.DoEvents();    string title = qD.GetValue(s, "Title");    this.lblStatus.Text = (++count).ToString();    if (title.Length > 0)    {        if (poemTitle.ContainsKey(title))            poemTitle[title]++;        else            poemTitle.Add(title, 1);    }}
然后再对 Dictionary<string, int>  排序:var poemTitleSorted = from pObj in poemTitle orderby pObj.Value descending select pObj;
Linq语句用起来太方便了。
然后把排序的结果添加到Listview就OK了~作者分析
和标题分析是大同小异的,这里不再累述。单字分析
先贴出代码了,思路很简单,就是提取出所有内容,拆分出每个字,再去掉标点符号,和标题分析一样进行统计。Dictionary<char, int> poemChar = new Dictionary<char, int>();string poemFile = this.txtFile.Text;QData qD = new QData(poemFile);int count = 0;long charCount = 0;if (File.Exists(poemFile)){    string[] sections = qD.GetAllSectionsArray();    Console.WriteLine("共有[{0}]首诗", sections.Length);    foreach (string s in sections)    {        Application.DoEvents();        string content = qD.GetValue(s, "Content");        this.lblStatus.Text = (++count).ToString();        charCount += content.Length;        foreach (char c in content)        {            if (poemChar.ContainsKey(c))                poemChar[c]++;            else                poemChar.Add(c, 1);        }    }    Console.WriteLine("共有[{0}]字", charCount);    if (poemChar.ContainsKey(','))        poemChar.Remove(',');    if (poemChar.ContainsKey('。'))        poemChar.Remove('。');    if (poemChar.ContainsKey('!'))        poemChar.Remove('!');    if (poemChar.ContainsKey('?'))        poemChar.Remove('?');    if (poemChar.ContainsKey('['))        poemChar.Remove('[');    if (poemChar.ContainsKey(']'))        poemChar.Remove(']');    if (poemChar.ContainsKey('-'))        poemChar.Remove('-');    Console.WriteLine("去除重复之后共有 {0} 字", poemChar.Count);    var poemTitleSorted = from pObj in poemChar orderby pObj.Value descending select pObj;  //Linq排序    this.listView.Clear();    this.listView.Columns.Add("单字", 200);    this.listView.Columns.Add("单字数量", 100);    this.listView.Columns.Add("比例", 100);    this.listView.BeginUpdate();    foreach (KeyValuePair<char, int> p in poemTitleSorted)    {        double ratio = (double)p.Value / (double)charCount * 100;        ListViewItem item = new ListViewItem(new string[] { p.Key.ToString(), p.Value.ToString(), ratio.ToString("F5") + "%" });        this.listView.Items.Add(item);    }    this.listView.EndUpdate();}qD.Close();诗句长度分析
一样贴出代码。思路是提取每首诗的内容之后,按标点符号拆分,我这里针对逗号、句号、问号和感叹号拆分,然后就能获取每个诗句的长度了。用Linq排个序就好了。string poemFile = this.txtFile.Text;Dictionary<string, int> poemType = new Dictionary<string, int>();QData qD = new QData(poemFile);int count = 0;if (File.Exists(poemFile)){    string[] sections = qD.GetAllSectionsArray();    Console.WriteLine("共有[{0}]首诗", sections.Length);    foreach (string s in sections)    {        Application.DoEvents();        string content = qD.GetValue(s, "Content");        this.lblStatus.Text = (++count).ToString();        int comma = content.IndexOf(',');        int period = content.IndexOf('。');        int questionMark = content.IndexOf('?');        int exclamationPoint = content.IndexOf('!');        comma = comma < 0 ? (period < 0 ? (questionMark < 0 ? exclamationPoint : questionMark) : period) : comma;        period = period < 0 ? comma : period;        questionMark = questionMark < 0 ? comma : questionMark;        exclamationPoint = exclamationPoint < 0 ? comma : exclamationPoint;        int min = comma < period ? comma : period;        min = min < questionMark ? min : questionMark;        min = min < exclamationPoint ? min : exclamationPoint;        min = min < 0 ? 0 : min;        string wordsOfFirst = content.Substring(0, min).Length.ToString();        content = NumberToChinese(wordsOfFirst) + "言";        if (content.Length > 0)        {            if (poemType.ContainsKey(content))                poemType[content]++;            else                poemType.Add(content, 1);        }    }}var poemTitleSorted = from pObj in poemType orderby pObj.Value descending select pObj;  //Linq排序this.listView.Clear();this.listView.Columns.Add("句子长度", 200);this.listView.Columns.Add("数量", 100);this.listView.Columns.Add("比例", 100);this.listView.BeginUpdate();foreach (KeyValuePair<string, int> p in poemTitleSorted){    double ratio = (double)p.Value / (double)count * 100;    ListViewItem item = new ListViewItem(new string[] { p.Key, p.Value.ToString(), ratio.ToString("F4") + "%" });    this.listView.Items.Add(item);}this.listView.EndUpdate();qD.Close();End
实现的核心代码基本就这些了,没有多少代码,我对C#不是很熟悉,代码写得比较冗长,请大家多多指教。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2017-5-22 17:19
抱歉,未能达到申请要求,申请不通过,可以关注论坛官方微信(吾爱破解论坛),等待开放注册通知。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 18:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表