我想玩文本统计,通过查看文本中的单词的相对频率(通常通过计算差异的绝对值之和)来成对地比较文本。这是文本数量的O(n ^ 2),因此每个文本中的预计算是可以的。我的问题是如何表示这样的统计数据。我尝试了两种方法:
Vector (T.Text,Double)
手动排序(在预计算期间),并给出两个这样的向量,通过递归函数计算总和。 zip
种类跟踪对的第一个元素的对齐方式,然后是fold
。
Map T.Text Double
然后使用mergeWithKey (\k x y -> Just abs (x-y)) id id
并使用foldl' (+) 0
在顶部烹饪相同的内容。
第二种方式更具表现力,因为Map
本质上是文本统计的真实含义,而且代码要短得多。但另一方面,Vector
大约快3倍,代价是冗长,而且不知何故感觉错了,就像Map
的天真实现一样。当然它错过了所有花哨的插入/更新/无论如何,但我不需要它。
我在这里遗漏了什么,比如第三个更适合任务的数据结构?
答案 0 :(得分:2)
假设您有两个文档,都有O(m)
个单词。然后,您的两个实现都需要O(m log m)
时间来比较文档。
Sorting document 1 into a Vector (Text, Double) ~ O(m log m)
Sorting document 2 into a Vector (Text, Double) ~ O(m log m)
stepping through vector 1 and 2 ~ O(m)
total: O( m log m )
Storing document 1 in a Map Text Double ~ O(m log m)
Storing document 2 in a Map Text Double ~ O(m log m)
stepping through map 1 and map 2 ~ O(m log m)
total: O( m log m )
所以你的解决方案是渐近等价的,但这并不意味着它们都应该具有相同的运行时。针对实际数据进行测试以查看具有较小系数的数据是分析的工作,并且在这一点上完全合适。 Vector解决方案可能不那么优雅,但完全可信,它更有效。
在此之后,您可以通过接受近似值继续优化运行时间: