发表于 2017-5-19 22:04

申请会员ID:DealiAxy

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
下面是软件截图:
http://blog.deali.cn/wp-content/uploads/2017/04/%E6%8E%A7%E5%88%B6%E5%8F%B0%E5%90%AF%E5%8A%A8.png
启动直接写成控制台的,反正就是自己用而已,粗糙一点无所谓,能用就行。
唐诗三百首匹配界面截图:
http://blog.deali.cn/wp-content/uploads/2017/04/%E5%8C%B9%E9%85%8D%E5%94%90%E8%AF%97%E4%B8%89%E7%99%BE%E9%A6%96.png
这里是从源文件读取数据并整理出每一首诗的标题、作者、内容。
全唐诗的匹配的界面:
http://blog.deali.cn/wp-content/uploads/2017/04/%E5%8C%B9%E9%85%8D%E5%85%A8%E5%94%90%E8%AF%97.png
你问我为什么这个的背景是深色的,我也不知道(摊手,反正当时就这么设置了= =…
由于全唐诗太多了,要打开并分析出来需要很长时间,所以这里用了小容量样本。
分析界面:
http://blog.deali.cn/wp-content/uploads/2017/04/%E5%8F%A4%E8%AF%97%E8%AF%8D%E5%88%86%E6%9E%90%E7%95%8C%E9%9D%A2.png
这个就是上次的文章里展示的,主要功能都在这里了。窗口主体是一个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++;      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++;            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++;            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

抱歉,未能达到申请要求,申请不通过,可以关注论坛官方微信(吾爱破解论坛),等待开放注册通知。
页: [1]
查看完整版本: 申请会员ID:DealiAxy