0

好的,所以我们需要将单词列表及其各自的位置存储在更大的文本中。我们被问到将位置表示为文本还是表示为位(Java 中的数据流)是否更有效。

我认为按位表示是最好的,因为文本“1024”占用 4*8=32 位,而如果表示为位则只有 11 位。

后续问题是索引应该保存在一两个文件中。在这里我想“也许你不能将文本和按位表示组合在一个文件中?” 这就是你需要两个文件的原因?

所以首要的问题是我可以将文本信息(单词)与按位信息(它的位置)结合起来存储在一个文件中吗?

4

2 回答 2

0

在真正需要什么方面太模糊了。

如果您有多达几百万个单词+位置,甚至都不要费心去想它。以最容易实现的任何格式存储;只有当您需要通过低带宽网络发送数据时,空间才会成为问题。

然后有可用的通用数据压缩,只需用 deflater 或 gzip(已经内置在 JRE 中)包装您的 Input/OutputStreams,您将获得相当好的压缩(文本的 50% 或更多)。这很容易超过你自己可以快速编写的内容。如果您需要更好的压缩,那么可以使用 XZ for java(实现 LZMA 压缩),开源。

如果您需要随机访问,那么您就走错了路,您将需要仔细设计访问模式的数据布局,并且存储应该只是第三个关注点。

于 2015-09-10T13:09:56.223 回答
-1

数字 1024 至少需要 2-4 个字节(即 16-32 位),因为您需要知道数字的结束位置和开始位置,因此它必须具有固定大小。如果您的位置非常大,例如 124058936,则您需要为每个数字使用 4 个字节(这比 9 个字节作为字符串表示要好)。

使用二进制文件,您还需要一种方法来了解字符串的开始和结束位置。您可以在它之前存储一个字节及其长度,然后像这样读取字符串:

byte[] arr = new byte[in.readByte()]; // in.readByte()*2 if the string is encoded in 16 bits
in.read(arr); // in is a FileInputStream / RandomAccessFile
String yourString = new String(arr, "US-ASCII");

另一种可能性是用空字符(00)终止您的字符串,但您需要为此创建自己的实现,因为默认情况下没有读者支持它(AFAIK)。

现在,真的值得将其存储为二进制数据吗?这实际上取决于您的位置有多大(因为字符串,如果在文本版本中用空格与它们的位置分开,将占用相同数量的字节)。我的建议是您使用文本版本,因为它可能更易于解析且更具可读性。

关于使用一两个文件,这并不重要。您可以将文本和二进制文件合并到同一个文件中,这将占用相同的空间(尽管将其放在两个单独的文件中总是会占用更多空间,并且可能会使编辑更加混乱)。

于 2015-09-10T12:55:10.150 回答