先瞎扯点别的。进入这个神圣的地方总需要些鞭策,阿西巴,我是被鞭策进来摆摊的程序猿。软件工程老师说,写程序,发博客,就来博客园。这是个号召力很强的口号。最近看网络营销 搜索引擎优化的书多一些,只能说王老师真的很厉害,至少在这一周因为这个作业的原因,我们学校的程序猿们对各大程序网站访问猛然骤增,网站流量,点击价值当然也是不菲,不过流量转化率就不好说了,当然了,三年多了都这样。再插一句,Google确实比百度做得好(其实只有中国用百度),SEO优化做的很到位,最近推出的“蜂鸟算法”也很棒,因为关键词明显好找么。

  

好了,言归正传了。

   

  题目主要是写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的10个词打印出来。 

  自从周四拿到题目以后,发现又要用到万恶的数据结构了,不得不说这是我的短板,所有上周20号到22号一直在看数据结构的书,当然还有google,在看书的期间确定了这个小程序编码的思路。

  1.首先进行文本文件的读取,将一个一个的单词分离出来,并对单词进行统计;

  2.然后对单词出现的次数进行排序;

  3.最后把频率最高的10个词打印出来。

  整理好思路以后,在23号的中午我终于准备拯救世界了,当然,我们宿舍的其他三位大神已经写完。。好了,不提我伤心的事了~~

经过分析后,主要就是解决两个算法的问题,

  (1).查找问题:统计出所有出现的单词以及他们出现的次数,这个方法挺多的,这次主要用了Hashtable,速度快,方便。

  在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对.

  下面的代码getAllWords和CountWord分别统计出了所有出现的单词以及他们出现的次数。并且用控制台和文件输出两种方式输出。

1.首先是计算单词的次数。

这里主要用到Hashtable 中各元素的虚拟子组存储桶,每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键key.并且把分割的所有的单词存放到一个名为List<WordInfo>的集合类中,最后用allWordInfos.Add(new WordInfo(key, (int)allWords[key]));在哈希表中添加了一个keyvalue键值对,为每一唯一键生成唯一哈希代码的哈希函数使得搜索性能更佳。

 1 public void CountWord(string inputFilePath, string outputFilePath)
 2         {
 3             Hashtable allWords = getAllWords(inputFilePath);
 4             List<WordInfo> allWordInfos = new List<WordInfo>();
 5             foreach (string key in allWords.Keys)
 6             {
 7                 allWordInfos.Add(new WordInfo(key, (int)allWords[key]));
 8             }
 9             qucikSort(allWordInfos, 0, allWordInfos.Count - 1);
10             writeToFile(allWordInfos, outputFilePath);
11         }

2.然后是统计出了所有出现的单词

在分析过程中发现还需要特别注意' ', ',', ';', '.', '!', '"'这些符号,所以在读取字节的时候用到了StreamReader的方法,主要是使其以一种特定的编码从字节流中读取字节。然后将读出来的字符串做处理,分成一个个的单词,然后就把所有英文单词对象添加到 Hashtable 的存储桶中,该存储桶与匹配该对象的哈希代码的哈希代码关联。在 Hashtable 内搜索一个值时,将为该值生成哈希代码,并且搜索与该哈希代码关联的存储桶。使得搜索效率变得很高。

 1 private Hashtable getAllWords(string filePath)
 2         {
 3             Hashtable allWords = new Hashtable(10240);
 4             using (StreamReader sr = new StreamReader(filePath, Encoding.Default))
 5             {
 6                 string line = null;
 7
 8                 char[] seperators = new char[] { ' ', ',', ';', '.', '!', '"' };
 9                 string[] words = null;
10                 while ((line = sr.ReadLine()) != null)
11                 {
12                     line = line.ToLower();
13                     words = line.Split(seperators, StringSplitOptions.RemoveEmptyEntries);
14                     if (words != null && words.Length > 0)
15                     {
16                         for (int i = 0; i < words.Length; i++)
17                         {
18                             if (allWords.ContainsKey(words[i]))
19                             {
20                                 allWords[words[i]] = (int)allWords[words[i]] + 1;
21                             }
22                             else
23                             {
24                                 allWords.Add(words[i], 1);
25                             }
26                         }
27                     }
28                 }
29             }
30             return allWords;
31         }

这个程序第二个问题就是

(2)排序问题,在这里用到了快速排序。

具体思路就是

1.分别设置low、hight指向序列的最左端、最右端;从序列中选一个进行排序(通常选最左端的值low指向的值),存入到value;
2.从hight端开始,查找比value小的,找到后讲该值放入到low指向的存储位中;同时将hight指向当前查到的值所在的位;
3.从low端开始,查找比value大的,找到后将该值放入到hight指向的存储为中,同时low指向当前查到的值所在位;
4.若low位小于hight位,返回2步;否则,将tmp值存入到空出来的low+1指向的位置,退出,返回low所在的位置lposition。
5.以lposition为界,将序列分成两部分,分别对两部分进行排序。

找了图,呵呵O(∩_∩)O~  神一样的图~~

 1 private void qucikSort(List<WordInfo> allWordInfos, int low, int high)
 2         {
 3             if (low >= high)
 4             {
 5                 return;
 6             }
 7             int pLow = low;
 8             int pHigh = high;
 9             WordInfo value = allWordInfos[low];
10             while (pLow < pHigh)
11             {
12                 while ((WordInfo.Compare(allWordInfos[pHigh], value) <= 0) && pHigh > pLow)
13                 {
14                     pHigh--;
15                 }
16                 if (WordInfo.Compare(allWordInfos[pHigh], value) > 0)
17                 {
18                     allWordInfos[pLow] = allWordInfos[pHigh];
19                     allWordInfos[pHigh] = value;
20                     pLow++;
21                 }
22                 while ((WordInfo.Compare(allWordInfos[pLow], value) >= 0) && pHigh > pLow)
23                 {
24                     pLow++;
25                 }
26                 if (WordInfo.Compare(allWordInfos[pLow], value) <0)
27                 {
28                     allWordInfos[pHigh] = allWordInfos[pLow];
29                     allWordInfos[pLow] = value;
30                     pHigh--;
31                 }
32             }
33             System.Diagnostics.Trace.Assert(pLow == pHigh);
34             qucikSort(allWordInfos, low, pLow - 1);
35             qucikSort(allWordInfos, pLow + 1, high);
36         }

此次快速排序可以将英文单词出现的频率全部从高到低排序出来存储在哈希表的存储桶里。

小插曲:在解决快速排序算法的时候,要感谢我们宿舍的各位亲们,编码抓狂的时候有你们足以O(∩_∩)O~ @我编程我快乐 @韩亚华 @FakerWang

最后再解决一些小问题

(3)控制台输出,文本输入输出,以及遍历出频率最高的10个词打印出来等问题。

 1 private void writeToFile(List<WordInfo> allWordInfos, string outputFilePath)
 2         {
 3             using (StreamWriter sw = new StreamWriter(outputFilePath, false, Encoding.Default))
 4             {
 5                 int i = 0;
 6                 sw.WriteLine("单词频率最高的10个词统计如下");
 7                 foreach (WordInfo wi in allWordInfos)
 8                 {
 9                         sw.WriteLine("{0}:{1}", wi.Word, wi.Count);//输出到文本文件
10                         Console.WriteLine("{0}:{1}", wi.Word, wi.Count);//输出到控制台
11                         i++;
12                         if (i == 10) break;
13                 }
14             }
15         }

行了,差不多了,截图纪念了。。

个人小项目总结:

最后总结下Hashtable的简单操作吧

1.在哈希表中添加一个keyvalue键值对:HashtableObject.Add(key,value);
 2.在哈希表中去除某个keyvalue键值对:HashtableObject.Remove(key);
 3.从哈希表中移除所有元素:           HashtableObject.Clear(); 
 4.判断哈希表是否包含特定键key:      HashtableObject.Contains(key);

以后肯定还得用。

这个小程序到这里也就结束了,也就是24号到27号,水平有限没办法。不过还是有个好玩的小插曲的,做完以后才发现我的运行效率是宿舍最快的,我们一起运行了一个5兆的英文文章,最慢的要20秒,我的3秒搞定,阿西巴,这是开挂的节奏啊,好了,差不多睡了,晚安了,各位程序猿和程序媛们~~

转载于:https://www.cnblogs.com/huiyuan/p/zhuhui.html

【学习笔记】C#中HashTable和快速排序的用法,从单词频率统计小程序写起相关推荐

  1. r语言c函数怎么用,R语言学习笔记——C#中如何使用R语言setwd()函数

    在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//") > setwd("e:\桌面\") > ...

  2. c#学习笔记05-treeview中添加图标

    创建树目录前面在学习笔记03中已经提到过 即树目录数据从XML文档中获取 添加图标主要用到ImageList控件 1.ImageList控件 在树目录对应存在的窗体中添加此控件 添加图标: 2.tre ...

  3. 20190328学习笔记 - JSP 中的 tag 文件

    20190328学习笔记 - JSP 中的 tag 文件 对于tag 文件 1. 引入 tag 文件 2. 在/WEB-INF/tags/sys 下,新增一个gridselect.tag文件 3. 在 ...

  4. Ext.Net学习笔记19:Ext.Net FormPanel 简单用法

    Ext.Net学习笔记19:Ext.Net FormPanel 简单用法 FormPanel是一个常用的控件,Ext.Net中的FormPanel控件同样具有非常丰富的功能,在接下来的笔记中我们将一起 ...

  5. Ext.Net学习笔记20:Ext.Net FormPanel 复杂用法

    Ext.Net学习笔记20:Ext.Net FormPanel 复杂用法 在上一篇笔记中我们介绍了Ext.Net的简单用法,并创建了一个简单的登录表单.今天我们将看一下如何更好是使用FormPanel ...

  6. 【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(二、JavaScript 异步编程)

    [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程.手写 Promise(课前准备) [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步 ...

  7. php中msubstr,PHP学习:thinkphp中字符截取函数msubstr()用法分析

    <PHP学习:thinkphp中字符截取函数msubstr()用法分析>要点: 本文介绍了PHP学习:thinkphp中字符截取函数msubstr()用法分析,希望对您有用.如果有疑问,可 ...

  8. SilverLight学习笔记--Silverlight中WebRequest通讯

    本文我们学习如何使用WebRequest类实现客户端和服务器端的通讯.      本例处理过程:在客户端,我们在文本框中输入任意文本,然后用POST方法向服务器端传递信息,服务器端收到从客户端传来的信 ...

  9. JavaScript学习笔记——JS中的变量复制、参数传递和作用域链

    今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习.今天学习笔记主要有这样几个关键字:变量.参数传递.执 ...

最新文章

  1. Centos5.5完整安装Cacti+Spine
  2. jquery 毫秒转换成日期_jQuery Datepicker – 如何将日期格式化为纪元时间戳(以秒为单位,而不是毫秒)...
  3. Mysql定期自动备份
  4. 深入理解JVM类文件格式
  5. 字符串处理(POJ1782)
  6. Android Studio 找不到EventBus/ButterKnife等第三方包解决方案
  7. mnist数据集图片提取出来
  8. 33 个 JavaScript 核心概念系列(四): == 与 ===
  9. uview组件得到回调的参数
  10. pandas把'm8[ns]'类型转换为int类型进行运算
  11. 最新emoji表情代码大全_8张最新创意好看的早上好表情图片大全 秋日温馨的早安祝福图片带字精选...
  12. matlab画直方图并拟合泊松分布,将泊松分布拟合为数据(直方图+直线)
  13. java 暴露接口_Java基于spring暴露接口供外部调用
  14. 硬核!深信服春招3面,终获20k入职offer!
  15. 别让just do it 误导了你
  16. 干货 | Elasticsearch 索引设计实战指南
  17. easyui onselect多选_easyUI combotree 多选取值
  18. 【PTA-乙级】1003-我要通过(手动感叹号)
  19. 计算机图形学核心期刊,中国图象图形学报是中文核心期刊吗
  20. 用h5的canvas实现动画的泡沫

热门文章

  1. STM32开发 -- WIFI那些事儿(一)
  2. 大数运算(7)——大数阶乘(求阶乘)
  3. 怎么判断ajax返回是否成功,如何判断jquery的ajax请求已经返回
  4. GCC 关键字inline探究
  5. @Transient不起作用的问题
  6. 使用photoview+viewpager实现图片缩放切换(类似微信朋友圈图片查看)
  7. 新一代开源Android渠道包生成工具Walle
  8. morlet小波matlab代码,morlet小波matlab程序
  9. Java连接open fire_java – 为什么我不能连接到openfire服务器?
  10. php 非阻塞post请求,PHP实现的CURL非阻塞调用类