如何将字符串拆分为具有多个重叠的较小字符串?

时间:2015-12-19 11:55:08

标签: javascript algorithm nested xhtml

我有大量的文本需要在给定的偏移+长度时突出显示。

提供的字符串是:

By Lesley Wroughton WASHINGTON Feb 25 (Reuters) - As scientists warn that climate change will lead to stronger storms the World Bank is launching on Monday the first disaster insurance plan to offer emergency money to 18 Caribbean countries immediately after they are hit by hurricanes or earthquakes.

我提供的ranges是:

var ranges = [
  {offset: 53, length: 10, highlightClass: 'a'},
  {offset: 74, length: 14, highlightClass: 'b'},
  {offset: 10, length: 20, highlightClass: 'a'},
  {offset: 20, length: 14, highlightClass: 'b'},
  {offset: 24, length: 3, highlightClass: 'c'},
  {offset: 28, length: 2, highlightClass: 'd'},
];

在继续之前,我会根据它们的偏移对所提供的范围进行排序,因此上面会产生:

var ranges = [
  {offset: 10, length: 20, highlightClass: 'a'},
  {offset: 20, length: 14, highlightClass: 'b'},
  {offset: 24, length: 3, highlightClass: 'c'},
  {offset: 28, length: 2, highlightClass: 'd'},
  {offset: 53, length: 10, highlightClass: 'a'},
  {offset: 74, length: 14, highlightClass: 'b'},
];

我需要做的是在这里突出显示各种范围及其相应的类名(例如,由ab两个类重叠的文本,而不是字符串将同时具有这两个范围适用于它的类)。到目前为止我所做的工作相当不错,如果一个单词只发生一次重叠,但是有多个重叠,就像在这种情况下华盛顿这个词,我的代码分解,因为我只检查'下一个范围'而不是尝试看到所有可用范围以及它们是否与现有范围重叠。

我通过简单地查看下一个范围是否与当前范围重叠来进行检查,如果是,我创建一个新范围并在下一个范围之前推送它,修改当前的一个长度和下一个的偏移量。 / p>

是否有更好的方法将字符串分解为多个范围,以适应可能重叠的所有范围?

1 个答案:

答案 0 :(得分:1)

使用格式良好的嵌套生成必要标记的一种粗暴方式是:

  1. 计算并存储每个范围的结束位置(在您的情况下为offset + length
  2. 按照起始位置(如您所做)对范围进行排序
  3. 创建一个与文本中有字符一样多的空数组的数组(让我们称之为character_classes)。
    • 注意:我们将外部数组用作列表,将内部数组用作堆栈。在JavaScript中,数组是两者的合适数据结构,但如果您愿意,可随意选择其他合适的类型。
    • character_classes中的每个堆栈将跟踪适用于文本中相应字符的所有类(文本中与该堆栈在character_classes中的位置具有相同位置的字符)。在从头到尾阅读文本时,它将按照应用顺序具有类。
  4. 遍布您的范围:
    • 将每个范围推送到character_classes中与该范围的起始位置或之后的任何字符对应的那些堆栈。
  5. 创建一个新的空字符串result
  6. 循环显示文字中的字符:

    对于每个角色(以及最后一个角色后的位置)

    • 从与该字符对应的堆栈中弹出范围,直到所有以此结尾的范围(请参阅步骤1中的计算结果)已被删除

      这样做:

      • 记住结束的所有弹出范围,包括他们的订单
      • 对于您弹出的每个范围(无论是否结束),将结束相应类别的标记附加到result 的顺序,弹出相应的范围
    • 将记住的范围(那些结束此处)推回到堆栈,按照弹出它们的相反顺序。 (因此,他们最终按照原来的顺序,只是没有结束在这里的那些。)

      这样做:

      • 按照您将范围推入堆栈的顺序将相应类开始的标记附加到result
    • 将文字中的字符附加到result
    • 从所有后续字符的堆栈中删除此处结束的范围,并按当前顺序保留其他范围。
  7. 完成后,result应包含正确标记的文字。