【发布时间】:2016-02-02 12:21:11
【问题描述】:
问题
我正在为 C 中的项目寻找一种数据结构来存储列表列表。我需要能够访问仅给出 n 的第 n 个列表(这些术语将被无序访问)。单个列表将包含 1 到 M 之间的整数(例如 M = 25 表示具体);外部列表包含其中 N 个。平均而言,单个列表比 M 更接近 1:在我的示例中,只有 20% 的列表具有 5 到 25 个元素。
显而易见的实现是一个长度为 N*M 的数组。但这是空间效率低下的:出于性能原因,结构不要占用太多内存很重要。有什么好的方法可以做到这一点?
上下文
我正在编写分解筛。外部数组表示从 Sb + 1 到 S(b+1) 的数字,每个数组都存储该范围内一个数字的质因数。结构越小,可以选择的 S 越大,从而减少(昂贵的)划分的数量。
这也提供了另一种优化途径:只存储大于或等于 L 的素数。好处是每个列表中不需要 floor(log_2(x = maximum number in range)) 元素,您只需要 floor( log_L(x))。 (上面的例子对应于 x = 10^12, L = 3。)缺点是重构分解需要对 L 以下的素数进行试除。
在我的应用程序中,每个因式分解都重构一次,因此在我的示例中,将 L 增加到下一个素数成本(略多于)10^12 个额外的除法;作为一个数量级,这在 3 GHz K10 上是每个 24-87 个操作或总共 2-8 小时。内存结构越高效,我需要花费的 2 到 8 个小时的时间就越少。 (另一方面,占用过多 CPU 工作的内存结构不值得,除非它们提供更好的权衡。)
【问题讨论】:
-
为什么不稍微作弊并持有一个包含 100 个第一个已知素数的小列表呢?你必须处理多大的 N?
-
为什么不存储一个包含 N 个指向列表的指针的数组?
-
预计 M 或 N 会更大吗?你能给出这些值的大致范围吗?
-
也 link 是一个设计良好的 C 数组列表实现的参考,它可能会为您省去使用 sieve.at 的麻烦
-
@GiladMitrani:N 通常在 10^5 到 10^8 左右,具体取决于高速缓存和主内存的速度/大小。如果要检查高达 10^12 的范围,这将需要 10^4 到 10^7 次程序调用。
标签: c math optimization data-structures prime-factoring