题目主要是写一个程序,分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的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键值对托福答案 www.qcwy123.com
 
   下面的代码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 内搜索一个值时,将为该值生成哈希代码,并且搜索与该哈希代码关联的存储桶。使得搜索效率变得很高托福答案 www.tfjy386.com
 
   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 }

C#中HashTable和快速排序的用法的更多相关文章

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

    先瞎扯点别的.进入这个神圣的地方总需要些鞭策,阿西巴,我是被鞭策进来摆摊的程序猿.软件工程老师说,写程序,发博客,就来博客园.这是个号召力很强的口号.最近看网络营销 搜索引擎优化的书多一些,只能说王老 ...

  2. Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法

    Java中List,ArrayList.Vector,map,HashTable,HashMap区别用法 标签: vectorhashmaplistjavaiteratorinteger ArrayL ...

  3. 1、C#中Hashtable、Dictionary详解以及写入和读取对比

    在本文中将从基础角度讲解HashTable.Dictionary的构造和通过程序进行插入读取对比. 一:HashTable 1.HashTable是一种散列表,他内部维护很多对Key-Value键值对 ...

  4. Spring mvc中@RequestMapping 6个基本用法

    Spring mvc中@RequestMapping 6个基本用法 spring mvc中的@RequestMapping的用法.  1)最基本的,方法级别上应用,例如: Java代码 @Reques ...

  5. Delphi中stringlist分割字符串的用法

    Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...

  6. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

  7. 标准C++中的string类的用法总结

    标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...

  8. html中的alt和title用法区别

    html中的alt和title用法区别 首先明确一下概念,alt是html标签的属性,而title既是html标签,又是html属性.title标签这个不用多说,网页的标题就是写在<title& ...

  9. .Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较

    参考资料 http://www.cnblogs.com/MichaelYin/archive/2011/02/14/1954724.html http://zhidao.baidu.com/link? ...

随机推荐

  1. HDU_1401——分步双向BFS,八进制位运算压缩,map存放hash

    Problem Description Solitaire is a game played on a chessboard 8x8. The rows and columns of the ches ...

  2. Hotel - poj 3667(求连续子区间)

    题意:有两种操作 1,从左往右找一个区间是 D 的连续序列,然后覆盖,返回区间最前面的数,如果没有输出0 2, 释放从L开始连续D的区间 分析:就是从左往右查找一个D的连续区间,可以使用三个值操作ls ...

  3. Xcode7 国际化

    1.第一步 HaiTing_xcodeproj.png 2.第二不 HaiTing_xcodeproj 2.png 3.第三步 Localizable_strings.png 5第五步 ZLBMeVi ...

  4. cocos2d 高仿doodle jump 无源代码

    1. 游戏视频 主角眼熟吗?没错,上次跑酷游戏中的"30"来Jump了,有三种道具.主角光环,竹蜻蜓.翅膀: 有两种怪物,螃蟹和鸟: 有5种板子.点击屏幕,30会把它的嘴巴3给发射 ...

  5. Android TagFlowLayout完全解析 一款针对Tag的布局(转)

    一.概述 本文之前,先提一下关于上篇博文的100多万访问量请无视,博文被刷,我也很郁闷,本来想把那个文章放到草稿箱,结果放不进去,还把日期弄更新了,实属无奈. ok,开始今天的博文,今天要说的是Tag ...

  6. PC端QQ协议解析之0825

    QQ协议0825代号解析,包括客户端发送包和服务器发送包. 主要借鉴的此篇文章,我自己也是重复造轮子. 基本信息 操作系统:windows7 QQ-Version:3643 客户端到服务器: 02:数 ...

  7. repeater 分页显示数据

    表名:ChinaStates 控件:Repeater 查询代码DA: public class ChinaStatesDA { private DataClassesDataContext Conte ...

  8. 本篇文章主要是对jquery+ajax+C#实现无刷新操作数据库数据的简单实例进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助

    我们知道同步执行和异步执行的区别,为了更好的提高用户的体验,我们都会采用异步方式去处理一些问题,毕竟单线程的同步可能回造成卡死等现象,很不友好,所以可以使用ajax来完成用户的体验,现在我们就来说说如 ...

  9. sql server语句

    一.基础1.说明:创建数据库CREATE DATABASE 数据库名2.说明:删除数据库drop database 数据库名3.说明:备份sql server--- 创建 备份数据的 deviceUS ...

  10. Dragger简介

    转自:http://www.apkbus.com/blog-705730-60435.html 什么是依赖注入 如果我们想要注入依赖,首先要理解依赖是什么.简单的说,依赖是我们代码中两个模块之间的耦合 ...