【发布时间】:2011-07-14 20:56:20
【问题描述】:
我正在编写一个程序来从文本文件中生成“多图”数据,这些数据基本上是字素与其在文本文件中出现频率之间的映射,例如:
aaaa : 0
aaab : 0
aaac : 0
...
thel : 10
them : 250
...
zzzz : 0
基本思想是,然后您可以根据多图数据对字符串“评分”,以测试它与文本文件语言的相似程度。评分功能必须非常快。因此,我希望通过使用 n 维数组来实现对数据的直接访问。例如:
data[n('t')][n('h')][n('e')][n('m')]
其中 n(char) 是一个对字符进行规范化的函数,例如 a -> 0、b -> 1、c -> 2 等。无论如何,问题在于:26^n 变大了,非常快!如果我每个元素使用 4 个字节,则不同的 n 值需要以下内存:
- 104 乙
- 3 KB
- 69 KB
- 2 MB
- 45 MB
- 1 GB
- 30 GB
- 778 GB
所以看起来当n > 3时,栈内存不足,而当n > 6时,大多数堆内存不足。理想情况下,我希望能够生成任何合理长度的多图文件——最多 10 个左右。有什么想法可以实现吗?
我考虑过为数组的每个元素使用少于一个字节的可能性。我真的只需要索引“a-z”,也许还有一些特殊字符(空格、标点符号),所以可能只需要 5 位(0-31)就可以了。这可能吗?如果可以的话,我可能会节省 38% 的内存。您认为这会如何影响时间复杂度?
一种选择是使用散列函数而不是数组。这意味着我只在实际存在的键上使用内存,而不是频率总是为 0 的“qxzf”。内存需求将大大减少,但我担心时间复杂度会受到严重影响。你怎么看?
也许我可以使用某种树数据结构?字形本身适合这种表示,但同样,时间复杂性肯定会受到打击。我认为访问数据需要“n”个步骤,而不是 1 个。
最后,我正在考虑对评分函数进行多线程处理。我宁愿不为每个线程分配数据的副本。您认为可以结合使用一两个与 Peterson 的算法来锁定元素吗?
提前致谢。
【问题讨论】:
-
您是否对简单地使用 Dictionary
进行过任何基准测试?它可能会更慢,但对于较大的 n,节省空间会比提前为每个可能的字符串预分配空间更好 -
我明天试试基准测试。我想它会慢几倍。它必须在每次评分时进行字符串比较。
-
我和布兰登在一起。首先简单地制作原型以获得真实世界的起点并根据需要添加复杂性。顺便说一句,我猜散列仍然足够接近恒定时间查找以使其可行(并且可能对缓存更友好。)
-
@Christopher:关于多线程,有多少评分函数位于临界区?待测字符串是否有自己的字素频率结构?您想对单个字符串进行多线程评分,还是每个线程都应该为不同的字符串评分?评分函数是否需要对共享字素频率结构的写入权限?
-
评分函数将是多线程的,每个线程采用不同的字符串进行评分。一旦生成多图数据,它就保持不变。评分函数的 CR 将仅从数据结构中读取。
标签: c++ c algorithm bitmap complexity-theory