individual_project_word_frequency (续)
果然又印证了闫导的话
需求一改,又开始写代码了
用了2小时吧
主要时间都用于询问需求了
主要是针对扩展模式,相同的是输出什么,大小写虽然不敏感但输出怎么输出等等
这是昨天写的算法:
首先说算法吧,想到的有2个
1、把所有word(包括重复的)排序,相同的(Extendedmode里相同的即相似的)肯定在按word排序后是连续的,相邻的两两之间比较一下,就可以确定word的value,再对value排序,时间复杂度nlogn,但在相同的词比较多的情况下,内存使用很大
2、对所有word,依次判断是否已存在,已存在直接把value+1,不存在则添加。
实现方法:用C++实现,map,Key是word,能在nlogn内首先单词的查找与插入,然后对所有单词进行排序,排序也是nlogn的时间
由于C++实现查询所有文件夹与文件等操作不是很方便,于是想用C#,C#有SortedDictionary可以实现与map一样的功能
但C#中,Dictionary是hash的,hash比平衡树要快一点,所以最后直接使用Dictionary了
至于大小写不敏感以及字符串处理,都是细节问题了,不再赘述了
由于要按字典序排,首先想到的就是使用算法1,直接全存ArrayList里,排序后相邻的比比,很容易实现,很快就写好了一个
但测试对于那个100多M的数据,很慢
里面the就有117万个,and有60多万,ArrayList里就有上千万个元素了,但不同的单词估计只有几千个,效率很低
于是很容易想到了利用第2个算法,映射再新加一个Directionary<string,string>,key与原Directionary中的key相同
映射的是此单词(主要指扩展模式下去掉所有尾数字的单词)对应的所有单词中字典序最小的一个
代码:
Dictionary<string, int> map = new Dictionary<string, int>(); //处理后的word
Dictionary<string, string> wordkey = new Dictionary<string, string>(); //相同word中最小的那个原word
if (map.ContainsKey(word1.ToString()))
{
map[word1.ToString()] = map[word1.ToString()] + 1;
if (string.CompareOrdinal(wordkey[word1.ToString()].ToString(),keyword.ToString()) > 0)
wordkey[word1.ToString()] = keyword.ToString();
}
else
{
map[word1.ToString()] = 1;
wordkey[word1.ToString()] = keyword.ToString();
}
应该很好理解吧
有个小问题,可以看到用的是string.CompareOrdinal
调试的时候发现,string.Compare里,顺序是'A','a','B','b',而string.CompareOrdinal里,才是ASCII序
测试数据:
100 a100 ab100 abc100 office1 office2 office3 office2108201
word123 Word456 Word woRd word word
hao123 hao123hao hao234
输出:
<Word>:6
<office1>:4
<hao123>:2
<abc100>:1
<hao123hao>:1
此数据中各类情况都有考虑,故不再粘其它数据了
还测试了那个100M的大数据以及以前在USACO过的60道题的文件的文件夹,结果都是正确的
新感想就是:适应了突然改需求的情况............总比没有需求好.....
PS : 有个惊喜,昨天那个第二代垃圾回收什么什么的警告居然没有了,继续求高人指导