0

希望标题不会太混乱。

我有一个目录,里面满是包含故事的文件。只有当它们之间的字符串不包含另一个列表中包含的任何句子时,我才需要获取两个句子之间的字符串列表(总是向前)。每个故事。

因此,例如,我有一个列表“大狗”、“她追他”、安妮咬嘴唇”等。

然后我有一个文件,它可能是一个包含谁知道什么的故事。我想找到“他跳到她后面”和“她吻了他”之间的字符串,但前提是它们之间的字符串不包含第一个列表中的任何句子,或者它们本身。

我已经找到了一些方法来做到这一点,但大多数都很慢,需要将近一个小时才能完成一个文件,我相信一定有更好更快的方法来做到这一点。请注意,我没有在此处添加它,因为我不想将解决方案限制在我正在做的事情上,这可能不是最好的方法。

4

1 回答 1

1

不确定您使用什么算法来解决您描述的问题,但这是我在这种情况下会做的

预处理:

  • 确保任何空白字符序列都减少为一个(空格、制表符等)。
  • 使整个文本小写或大写。

过程:

  • 将所有标记的单词预加载到内存(有序列表以使用二进制搜索,理论上这个过程应该只在您第一次创建列表时消耗时间,继续对条目进行排序并将它们以您以后可以加载的格式保存,任何进一步的添加应该进行二进制搜索以确定单词是否在列表中并将条目放在相应的位置/槽中)。
  • 将所有流行语预加载到内存中(在这里我们可以使用与加载单词相同的方法)。
  • 遍历文件并保留与标记列表匹配的任何单词的偏移量/位置和长度。考虑到大文件,偏移量应该很长。
  • 查找标记单词的序列。第一个单词之后的任何匹配都是序列的候选,因为我们删除了所有空白字符序列,如果这个单词的偏移量等于前一个单词的偏移量加上前一个单词,我们可以确定 WordN 是序列的一部分长度加 1,这里的 1 代表分隔两个单词的空白字符。word2Offset = word1Offset + word1Length + 1。
  • 检查找到的任何序列是否匹配开始或匹配流行语。

实施资产:

  • 单词:一个简单的字符串就足以表示单词。所有单词必须以小写或大写形式存储。
  • 组件:组件是一个结构,它包含一个单词和在文件中找到它的文件的偏移量
  • 短语:是两个或多个组件的组合,一个简单的列表就足够了。
  • 一次读取一个字符可以帮助快速确定单词和单词的顺序。例如,每个空格都意味着读取了一个新组件,基本上是一个单词,所以我们可以在那里使用检查它是否匹配,如果它匹配并且是第一个匹配,我们不知道它是否是一个序列,但是一旦我们读取第二个或第三个单词并且我们知道是否匹配,我们可以检查当前偏移量是否遵循我们之前描述的规则。

检查阶段

  • 如果没有标记任何单词,则不会匹配任何短语。几乎不可能,但谁知道呢。
  • 文件中的任何单词匹配序列都代表短语检查的候选对象。
  • 检查词长和后面的词内容以检查流行语和候选词之间的匹配。在这里,您可以检查部分或整个短语是否匹配。

获取两个序列阶段之间的文本。

由于阶段只是一个组件列表,我们只需从第一个短语的最后一个单词的偏移量和长度之和到第二个短语的第一个单词的偏移量读取文件。

From = PhaseALastWordOffset + PhaseALastWordLength
To = PhaseBFirstWordOffset
内容 = StoryFile.readSegment(From, To);

希望能帮助到你。

于 2012-04-11T03:31:08.143 回答