课后作业3:个人项目(词频统计及其效能分析)
1) 博客开头给出自己的基本信息,格式建议如下:
- 学号:2017****7217;
- 姓名:卢冠宇
- 本次作业码云:https://gitee.com/The_Old_Cousin/word_frequency_count/tree/master
2) 程序分析,对程序中的四个函数做简要说明。要求附上每一段代码及对应的说明。
1 using Microsoft.Win32; 2 using System; 3 using System.Collections; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Windows; 8 9 namespace WpfApp1 10 { 11 /// <summary> 12 /// MainWindow.xaml 的交互逻辑 13 /// </summary> 14 public partial class MainWindow : Window 15 { 16 public MainWindow() 17 { 18 InitializeComponent(); 19 } 20 21 /// <summary> 22 /// 将打开的txt内容读到T2这个TextBlock,或者说读文件到缓冲区 23 /// </summary> 24 /// <param name="sender"></param> 25 /// <param name="e"></param> 26 private void Button_Click_1(object sender, RoutedEventArgs e) 27 { 28 OpenFileDialog openFileDialog = new OpenFileDialog(); 29 openFileDialog.Title = "选择数据源文件"; 30 openFileDialog.Filter = "txt文件|*.txt|所有文件|*.*"; 31 openFileDialog.FileName = string.Empty; 32 openFileDialog.FilterIndex = 1; 33 openFileDialog.Multiselect = false; 34 openFileDialog.RestoreDirectory = true; 35 openFileDialog.DefaultExt = "txt"; 36 if (openFileDialog.ShowDialog() == false) 37 { 38 return; 39 } 40 41 string contents = System.IO.File.ReadAllText(openFileDialog.FileName, Encoding.Default); 42 T2.Text = contents; 43 } 44 45 /// <summary> 46 /// 统计每个单词的频率,存放在字典word_freq 47 /// </summary> 48 /// <param name="strword"></param> 49 /// <returns>返回一个word_freq</returns> 50 private Dictionary<string, int> process_Buffer(ArrayList strword) { 51 52 Hashtable ht = new Hashtable(); 53 foreach (string i in strword)//以哈夫曼树记录统计词频,遍历wtrword 54 if (!ht.Contains(i)) 55 ht.Add(i, 1); 56 else 57 { 58 ht[i] = (int)ht[i] + 1; 59 } 60 61 Dictionary<string, int> word_freq = new Dictionary<string, int>(); 62 foreach (DictionaryEntry de in ht)//导入字典 63 { 64 word_freq.Add(de.Key.ToString(), Convert.ToInt32(de.Value)); 65 } 66 67 word_freq = (from entry in word_freq orderby entry.Value ascending select entry).ToDictionary(pair => pair.Key, pair => pair.Value); 68 return word_freq; 69 } 70 71 /// <summary> 72 /// 疯狂切字符串 73 /// </summary> 74 /// <param name="strtext_low">一个已经变成小写的文本</param> 75 /// <returns>返回一个已经被切好的ArrayList字符串列表</returns> 76 private ArrayList separateword(string strtext_low) 77 { 78 ArrayList sepword = new ArrayList();//定义一个动态数组用于传进已转换小写的数组 79 string strtext = strtext_low; 80 strtext = strtext.Replace(',', ' ');//用Replace()方法将‘,’,‘。’转化为空格 81 strtext = strtext.Replace('.', ' '); 82 string[] word = new string[500];//定义一个500长度的数组接收转换完成的单词 83 word = strtext.Split(' ');//使用Split()方法分割单词 84 foreach (string i in word)//遍历循环将其传入动态数组sepword 85 sepword.Add(i); 86 return sepword; 87 } 88 89 90 /// <summary> 91 /// 相当于最后的“if __name__ == "__main__":”的执行 92 /// </summary> 93 /// <param name="sender"></param> 94 /// <param name="e"></param> 95 private void Button_Click_2(object sender, RoutedEventArgs e) 96 { 97 T1.Text = ""; 98 int i = 0; 99 foreach (var item in process_Buffer(separateword(T2.Text.ToLower())).Reverse()) 100 { 101 if (i > 10) 102 { 103 break; 104 } 105 if (item.Key != "") 106 { 107 string str = string.Format("[" + i + "]" + "{0,-15} {1,3}", item.Key, item.Value); 108 T1.Text = T1.Text + str + "\r\n"; 109 } 110 i++; 111 } 112 i = 0; 113 114 } 115 116 } 117 }
3) 性能分析结果及改进。
- 指出执行次数最多的代码,执行时间最长的代码。
- 执行次数最多:
word_freq.Add(de.Key.ToString(), Convert.ToInt32(de.Value));
- 执行时间最长:
string contents = System.IO.File.ReadAllText(openFileDialog.FileName, Encoding.Default);
- 执行次数最多:
- 给出改进优化的方法以及你的改进代码
- 执行次数最多:执行次数最多的代码已经达到准线型饱和,目前为止未发现任何改进优化方法。
- 执行时间最长:使用预缓存和多线程来进行读取操作,目前为止我们没有学过相关知识以至于达到我们可以进行对其优化。
4) 程序运行命令、运行结果截图以及改进后的程序运行命令及结果截图 。
性能统计概况
5) 给出你对此次任务的总结与反思。
简单实现了对词频统计及其效能分析,很明显,效能是一个程序性能的决定性表现之一。我们还需要学习更多常用高效的算法和编程基础知识,来拓展我们对软件工程的学习。