Excel / SharedStrings的排序算法


10

在Excel中,它们将字符串“压缩”为数字映射(尽管我不确定在这种情况下compress这个词是否正确)。这是下面显示的示例:

在此处输入图片说明

虽然这有助于减少总体文件大小和内存占用量,但是Excel如何对字符串字段进行排序?是否每个字符串都需要进行查找映射:如果是这样,这不会大大增加/减慢对字符串字段进行排序的成本(如果有1M的值,则不会进行1M的键查找)不重要的)。关于此的两个问题:

  1. 是在Excel应用程序本身中使用共享字符串,还是仅在保存数据时使用共享字符串?
  2. 那么在现场排序的示例算法是什么?任何语言都可以(C,C#,C ++,Python)。

我也会对此有知识的答案感兴趣。我只能猜测它与内存缓存有关,但很容易出错。
PeterT

我认为此映射存在于文档的物理XML表示中的事实与Excel在运行时内部表示数据的方式无关。我相信以原始方式表示数据列的计算效率更高(尽管可以通过多种方式完成)。
alxrcs

@alxrcs是否有任何文档或书籍进入Excel的内部,类似于SQLServer的类似内容?amazon.com/Pro-Server-Internals-Dmitri-Korotkevitch/dp / ...,或者基本上是ms团队之外的黑匣子?
David542

不确定,抱歉。您可以在网上找到一些有关文件格式的规范,但是我认为关于Excel运行时内部组件的详细信息不那么容易找到。
alxrcs

无论如何,从第二个问题开始,我怀疑您对理论比对Excel的细节更感兴趣,对吗?
alxrcs

Answers:


0

我无法找到Excel SharedStringTable在运行时如何精确地将带有元素的单元格存储在内存中,但是SharedStringTable假设将元素存储为数组,则将它们存储为项目的索引仅需要一个额外的解除引用即可访问它们。因此,我的猜测是这是完成的方式。那是最简单的方法,并且使其更快的唯一方法是使运行时表示形式SharedStringTable已经按元素排序。在这种情况下,按索引排序等同于按值排序。但是,这种方法使插入操作成本很高,因为将新字符串插入表的中间时,所有大于其应增加的索引都会增加,并且文档中此类单元格的数量可能非常大,直到所有指的细胞SharedStringTable

如果单元格包含的索引与文件中的索引相同,则以下是如何根据columnValue向量所指向的字符串对向量所表示的单元格进行排序的方式sharedStrings(在C ++中,因为您说的没有区别),成本为2每个比较操作的额外取消引用:

// sort indexes from columnValue based on comparing values in sharedStrings
sort(columnValue.begin(), columnValue.end(), 
     [&sharedStrings](size_t i1, size_t i2){return sharedStrings[i1] < sharedStrings[i2];});

它不在OP中,但是反向SharedStringTable查找操作很慢,并且将元素缓存到字典中很有帮助。


0

Microsoft Excel共享字符串表

共享字符串表和ISO标准定义的Open XML标准-ISO / IEC 29500-1:2016(E)

共享字符串的正式定义(引自ISO文档)

共享字符串表

字符串值可以直接存储在电子表格单元格元素中;但是,将相同的值存储在多个单元格元素中可能会导致工作表零件非常大,从而可能导致性能下降。共享字符串表是在工作簿之间共享的字符串值的索引列表,允许实现仅存储一次值。

可以从以下位置下载关于共享字符串的ISO标准:

https://standards.iso.org/ittf/PubliclyAvailableStandards/c071691_ISO_IEC_29500-1_2016.zip

回答有关此主题的问题

问题1: 共享字符串是在Excel应用程序本身内部使用还是仅在保存数据时使用?

答: 共享字符串仅在保存文档IE时由Excel使用,仅用于将电子表格存储为文件形式。

但是,当打开文件进行显示时,单元格中会填充有从共享字符串表中提取的实际字符串值。

--

问题2:那么在现场排序的示例算法是什么?任何语言都可以(C,C#,C ++,Python)。

答: 对于像Excel这样的应用程序,我猜想Quick sort的特殊专有变体 是最有可能用于对字符串值进行排序的算法。

Excel的限制为1,048,576行。对于这种尺寸,快速排序绝对是赢家。快速排序可以为这种规模的数据集产生非常有效的结果。

这是在C ++中用于对字符串进行排序的Quick Sort实现的链接:

http://www.cplusplus.com/forum/beginner/101599/


2
快速排序将在字符串本身上,您需要取消引用指针或执行查找映射一百万次,但是,不是吗?我认为这个答案基本上只是说“是的,它有共享字符串。这是在没有共享字符串的情况下进行排序的方法”。
David542

2
共享字符串表仅用于将文件内容存储到磁盘。ISO标准未指定打开应用程序时必须如何填充单元格。如果用从共享字符串表中提取的字符串值的副本填充单元格,则可以避免取消引用。
Gopinath

1
我知道了。是的,我的主要兴趣是在内存中如何处理存储中/存储以外的问题。您对此部分有任何见解吗?
David542

在excel排序中,用户必须将排序顺序指定为列列表(例如:按列A排序,然后按B排序,然后按C排序,然后按D排序)。假设列A包含重复的字符串。排序时,列A的所有具有相同值的行将按“列B”的值进行排序。如果B的单元格也包含重复值,则将在列C上进行排序...依此类推,直到找到具有唯一值的列。如果没有列具有唯一值,那么将跳过行。
Gopinath
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.