虽然第一个Project还有点小问题需要修改,但是大体已经差不多了,先把blog记在这里,算是开博第一篇吧!
1.项目预计的用时
本来看到这个题的时候想的并不多,但是看了老师的要求才觉得如此麻烦ORZ……尤其是动不动出现的o points更是吓得我认认真真的把老师的要求读了好几遍,可怜我一个英语这么差的人真不容易……
项目要求要用C#或者C++,这两个语言我都是略懂,但是有些用法还是不了解的,因此:
-计划学习C#+百度一些用法的时间:2小时
-项目本身打算写两个类,一个是遍历搜索文件夹的,另外一个用来统计单词的。感谢上学期OO的吴际老师,我上学期Java写的遍历文件夹的代码还能拿来用,因此这部分计划用时:2小时
-另外一个统计单词的类就要相当于要重新写了,不过考虑到也就是正则表达式然后再提取的问题,也没做多想,计划用时:4小时
2.项目实际用时
说起来这都是泪啊!!!真正写起来我才发现老师的要求多么让我想跪!我整个一天坐立不安,心绪不宁,一会儿实在写不下去上床睡一会一睡就是2个多小时,一会儿在苦思冥想Extended Mode的算法一个人大晚上坐在绿园边上啃着烧饼夹里脊!最最坑爹的一件事情是,到了晚上,我都已经写完了,然后一个同学来问我问题,我才发现我看的是老师去年的要求!今年和去年的这部分完!全!不!一!样!!天哪,想死的心都有了。所幸,我在读了今年的要求以后,发现好像比去年的要简单了(去年那段代码我还没删呢都是泪啊!……
于是实际用时是:
-学习和C#和百度相关内容:估计花了预计的2小时吧……相关网页一直都没关,不过这个时间是离散的,基本都是有什么问题不会才百度然后查找解决方案。
-完成遍历文件夹的类:2小时左右。本来觉得只是修改一下Java的代码应该比较容易,因为以前也做过从C#移植到Java的工作,结果坑爹的是发现C#的File类完全没有Java的好用,于是学习了一下C#这方面的操作方法(吐槽:Directory和File属于两类还真是好难用啊……
-完成统计单词的类:12+小时…… 先不说在这部分坑了一下把题看错了耽误了多少时间,关于正则表达式的构建也够麻烦……本来想的是很简单的就像老师描述的那样构建,后来发现123file这种情况表达式会把file当成一个单词提取出来,问了老师老师说不行T T 为了不得o points还得苦思冥想解决办法,来来回回试着改了好几次正则表达式还是被MatchCollection这个非重叠匹配坑了,于是只好回归最简单的解决方法……如果小伙伴们有好的正则表达式麻烦告诉我下。
还有就是我用的是System.Linq进行的排序,这个默认的字典序排出来真的是字典的样子,不是按照ASCII来的也是跪了= =问了老师也不知道行不行老师还没回复……不行还得改……(关于字典序的问题,请大家直接跳到4.(4),做了点更新)
3.项目的表现和性能的分析
需要一提的是我在思考算法的时候就觉得哈希表很好用(对于频繁查找单词只有O(1)的复杂度确实很理想),于是就采用了Dictionary这个哈希表的结构,再加上排序什么的都用了Linq内置的方法,因此感觉性能上还可以。我曾经试图让其扫描VS2012的安装文件夹(3G大),用时是1min25sec,统计的结果是1.06M,应该还可以提高的吧!只是我现在还没有做什么性能优化的工作,如果以后做了再补上这里。(这段是最初写的内容)
修改内容:
这是VS2012分析出来的扫描VS安装文件夹(3G大)的结果,其实我也看不太懂还在研究中……
下面这张图是相关函数的使用情况,但是不知道为什么函数名加载不出来……麻烦了解的同学能解答一下!
下图是性能分析系统给出的警告,可见程序在垃圾回收这里有很多开销:
我推测是因为我对Substring方法的过多使用,由于调整了算法,基本上每次循环都需要使用Substring。而Substring似乎每次会创建一个新对象的引用(有待查证),那这开销是非常大的了。我用一个小样例测试时系统也给出了这方面的警告:
关于Substring的优化还没有做,等研究清楚了再补上。
补上优化结果:
按照我昨天的猜测,我今天对Substring这句进行了优化。其实之所以用这个方法是为了避免造成非重叠匹配,我想到很蠢的方法就是把已经匹配的串的第一个单词前的内容全都删掉,得到新的源串。后来我就想,怎么可能会没有从规定下标开始匹配的方法呢?一查,果然有Regex.Match(string input, int startat)这个重载方法,于是果断删掉Substring,重新进行性能测试。以下是新的测试结果,还是对VS2012的安装文件夹(3G大)的扫描:
从上图可见,平均CPU使用率比原来降低了不少,最高都没有突破60%(其实我怀疑这个是不是和机器当前的负载也有关?我今天测试前清理了一下内存)。
执行单个工作最多的函数占的比例也明显下降了,见下图:
最终警告也成功消除了,这个优化应该算是成功的!见下图:
最后我对优化后统计这个3G文件夹的词频用时进行了统计:
-统计单个词 : 用时15.97s,结果1.06M
-统计连续两个词: 用时18.8s
-统计连续三个词: 用时19.16s
这真是比原来的1min25sec快多了啊~
4.项目的测试样例
今天来补充一下测试样例(只对一些结果进行了截图):
-(1)、测试大小写合并能力
file123 file File 123file files
说明:本例主要测试能否在大小写不敏感的情况下将相同的单词合并并选取字典序在前的单词。除此之外,123file不是一个单词,其中的file由于并不是由空白符和非字母数字分隔的,也不能作为一个单词,因此File出现的次数是2(这里改了好久我会说)。
期待&运行结果:<File>:2
<file123>:1
<files>:1
-(2)、测试词的区分能力
abbsd-dnsd((@(@*# fahfh
123file*$(^( File
说明:本例主要测试能否根据分隔要求挑出正确的单词
期待&运行结果:<File>:1
<abbsd>:1
<dnsd>:1
<fahfh>:1
-(3)、测试老师的博客
样例太长了就不贴了,请大家直接进http://www.cnblogs.com/jiel/p/3978727.html,就是直接把老师的博客内容copy了一下。老师的博客格式是比较规范的,没有乱七八糟的符号,基本都是空格分隔,是一个很理想的测试样例(谁说老师博客没什么的!老师博客深藏功与名!我之前跑的结果都是错的今天才发现了错误!!)也算是对实际问题的一个分析吧!对老师的博客分析结果如下:
a.单个词词频分析(只贴2张图)
运行结果:
b.连续的两个词
运行结果:
c.连续的三个词
运行结果:
请注意:如果有哪位同学对老师博客内容的分析结果和我不一致的请快点告诉我>_<(我怕o points……
-(4)、测试词的排序能力
File file “windows”, “windows95” and “windows7” ONE WORD;
Office” “Office15” “iPhone4” “Iphone5” “windows”windows32a
“windows95”, “windows98” “windows2000”
说明:本例本来想测试程序对于字典序的排序情况,奈何Linq的字典序就是不按ASCII出牌!我和老师关于字典序的最新讨论请大家阅读http://www.cnblogs.com/jiel/p/3978727.html的评论部分,其间我还参考了http://*.com/questions/22700300/how-does-orderby-work-with-regard-to-strings-in-c这个问答以及MSDN上的解释http://msdn.microsoft.com/en-us/library/system.stringcomparer.aspx,但是!最后我还是默认了Linq这种字典序的排法了!如果大家和我的顺序是一样的我就认同这种排法了!
最新更新:在老师的回复下,这个问题终于解决了!终于能按照ASCII顺序排了~请大家结合Linq使用.OrderBy(o => o, StringComparer.Ordinal)即可(不是 StringComparer.InvariantCulture哦,这个用了就是上面的结果)。其实也可以自己写一个按照ASCII排序的接口^_^(你不就是懒不想写吗!
运行结果:
-(5)、测试包含中文的情况
Myapp.exe C:\Users\dell\Desktop\Test
Myapp.exe -e2 C:\Users\dell\Desktop\Test
Myapp.exe -e3 C:\Users\dell\Desktop\Test
Myapp.exe -e4 C:\Users\dell\Desktop\Test
Myapp.exe C:\Users\dell\Desktop\Test\Myapp
Myapp.exe C:\Users\dell\Desktop\Test\Receiver
Myapp.exe C:\Users\dell\Desktop\Test\测试空文件夹
Myapp.exe C:\Users\dell\Desktop\Test\1_测试大小写合并能力.txt
Myapp.exe C:\Users\dell\Desktop\Test\2_测试词的区分能力.txt
Myapp.exe -e2 C:\Users\dell\Desktop\Test\2_测试词的区分能力.txt
Myapp.exe -e3 C:\Users\dell\Desktop\Test\2_测试词的区分能力.txt
Myapp.exe C:\Users\dell\Desktop\Test\3_老师的博客.txt
Myapp.exe -e2 C:\Users\dell\Desktop\Test\3_老师的博客.txt
Myapp.exe -e3 C:\Users\dell\Desktop\Test\3_老师的博客.txt
Myapp.exe C:\Users\dell\Desktop\Test\4_测试词的排序能力.txt
Myapp.exe C:\Users\dell\Desktop\Test\5_测试包含中文的情况.txt
Myapp.exe -e3 C:\Users\dell\Desktop\Test\6_测试连续三词的情况.txt
Myapp.exe -e2 C:\Users\dell\Desktop\Test\7_超级变态的连续两词情况.txt
Myapp.exe -e3 "D:\Microsoft Visual Studio 11.0"
说明:我才不会说这是我准备的指令集!这条要多谢@徐大侠的提醒。按照老师的规定,中文应该也算是一个分隔符了,所以中文应该不影响测试结果才是正常。这个例子顺便也测试了少于3个字母的比如e2、C是不能作为单词的!
期待&运行结果:
-(6)、测试连续三词的情况
"how are you
how Are you
fine thank you and YOU
fine Thank you And you
fine thank YOU and"
说明:本例测试连续三个词出现的频度,谢谢天神提供的样例!帮助我发现了bug!测出来不对的童鞋估计都和我犯了一样的错误T T
期待&运行结果:
-(7)、测试超级变态的连续两词情况
123file file File FILE
说明:骚年们别吐槽说这个不变态啊!我一直都在思考这种情况的解决方案(我是不是太弱了……)这个例子不但包含了单词的识别、大小写的归并,最最重要的是,帮我发现了算法和正则表达式设计上的问题(具体原因就不细说了,也许大家没这个问题)
期待&运行结果:
<File FILE>:2
没错!结果应该是2次!答案是3次的同学想想是不是把123file file里那个"file file"截取出来了;答案是1次的同学想想是不是被非重叠匹配给坑了(这两个错我都犯过!)
最最重要的是,答案是2次的同学仔细想想是真的对了还是上面那两个错一起犯了ORZ!!
另外,关于大小写,我觉得“File FILE”是一个单词,所以结果不是“FILE FILE”,这点我和天神想的一样,请大家参考天神blog(http://www.cnblogs.com/buaasts/p/3985877.html)第5个case。
-(8)、测试空文件夹或空文件
这个没什么说的,空的话输出文件就是空
-(9)、测试包含“.h",".cs",".cpp","txt"文件的文件夹
这个我拉进来了一个C#项目的文件夹,主要是看看程序能否识别这些文件
-(10)、测试超大的文件夹
这个就是上面提到的运行了1min25sec的测试……大家也可以扫描一下VS2012安装目录。这个主要是为了测试程序性能及数据结构是否合理。放两张连续2词和3词的结果,单词的太长了就不截图了。p.s :Microsoft Visual Studio 11.0这个文件夹目录注意加引号。
至于我怎么确保自己的程序是正确的,实话说我也不能确保自己的程序是完全正确的……软件的测试就是靠自测和用户的测试然后不断反馈bug进行修复,自测方面一些比较简短的文件我就自己统计一下出现次数,长的就没办法了。用户测试就依靠和同学们相互测试样例然后对照答案了。
5.学到了什么
其实这次小项目还是学了蛮多的,在这之前我还从没用C#或C++写过这种比较复杂的小项目,出于对C++的畏惧我选择了和Java比较相似的C#。虽然和Java相似但有些不熟悉的地方比如Dictionary和Linq的使用还得查找资料,选择了CS这个专业果然就要接受学习无止境的结果!这次也是我第一次使用VS2012这个IDE,微软出的东西果然功能强大,不过我还得研究一下性能分析那个东西怎么回事= = 感觉自己在算法的思考上还是挺捉襟见肘的,数据结构也要思考半天,还是因为不熟悉吧!希望以后的Projects能更顺利点~ P.S:我好像隐隐看见了电梯……吴际老师我又要谢谢你了( ̄_, ̄ )
最后还要表示对宋天舒同学的感谢!我阅读了他的博客后得到了很多启发,也发现了自己的一些错误。关键是人家英语写了全文诶!英语废有心无力又是跪了Σ( ° △ °|||)︴
从周六开始写程序到今天算是完成了Individual Project的所有内容,终于长舒一口气。不过我发现SE课让我爱上了写博客,这几天基本上一直都在改博客OTZ,昨晚改博客到3点也是醉了……不过博客是一个很好的学习工具啊!以前都是只看别人的,自己只写过一篇也够懒。这篇博应该没什么大问题需要改了,于是现在是2014/9/24 0:15 封贴啦~ 如果有什么错误欢迎小伙伴一起讨论哦~~
2014.9.22 凌晨