【发布时间】:2009-08-18 13:08:46
【问题描述】:
我有一个大的二进制文件(1 MB
编辑:索引文件中的字符串按排序顺序排列。
【问题讨论】:
-
我也遇到过类似的情况。使用传统的字符串搜索逐个字符读取(假设为 ASCII)。由于您已经有一个索引文件,我认为您无法进一步提高性能。
我有一个大的二进制文件(1 MB
编辑:索引文件中的字符串按排序顺序排列。
【问题讨论】:
【讨论】:
IndexOf,则不会。但是对于流式数据,.NET 不提供搜索方式,在这种情况下推荐使用 Boyer-Moore 算法。
按排序顺序(按字符串)存储 {string, size, offset} 元组,并对字符串使用二进制搜索。
您还可以在文件的开头存储字符串的每个首字母的偏移量。例如,如果以 'a' 开头的字符串从位置 120 开始,而以 'b' 开头的字符串在文件中的位置 2000 开始,您可以使用类似 120, 2000, ...
【讨论】:
如果编码是固定的(ASCII),则相对简单。打开一个二进制流,逐字节读取并匹配目标字符串的第一个字符。
如果您有使用另一种 (UTF-8) 编码的字符串,它会变得更加棘手。
【讨论】:
首先,在文件上使用内存映射。这将比将其读入 RAM 效率更高,因为只有一个副本而不是两个副本(一个在您的程序中,一个在文件缓存中)。
如果每个字符串都是固定长度的,那么二分查找就非常容易,因为您可以将内存视为字符数组的数组。
如果每个字符串都是可变长度但以 0 结尾,那么您可以使用二进制搜索的变体,跳到字符串列表的中间,搜索下一个 0,然后测试下一个字符串。然后向前或向后跳到字符串列表的 1/4 或 3/4 并重复。
如果每个字符串在 Pascal 样式中都是可变长度的,并且在开头有一个字节数,那就更棘手了。对于不频繁的搜索,从一开始的线性搜索不会太慢。如果您正在寻找完全匹配的字符串,请不要忘记您可以通过检查长度是否不匹配来跳过大多数字符串。
如果您必须经常搜索列表,那么构建一个指向字符串列表的 char 指针数组将再次使二进制搜索变得非常容易。如果这个文件真的是一个用于快速搜索的索引文件,那么它可能已经在某个地方有这个,除非设计者打算在加载文件时构建一个 char 指针数组。
【讨论】: