Java 有效地检查子字符串并替换它们-我可以在这里提高性能吗?

Java 有效地检查子字符串并替换它们-我可以在这里提高性能吗?,java,Java,我需要检查数百万个字符串的缩写,并用完整版本替换它们。由于数据原因,仅应替换以逗号结尾的缩写。字符串可以包含多个缩写 我有一个包含缩写->完整版本对的查找表,它包含大约600对 我当前的设置看起来像这样。启动时,我使用Jackson从csv文件创建了一个简短的实例列表,并将它们保存在一个单例中: public static class ShortForm{ public String fullword; public String abbreviation; } List<

我需要检查数百万个字符串的缩写,并用完整版本替换它们。由于数据原因,仅应替换以逗号结尾的缩写。字符串可以包含多个缩写

我有一个包含缩写->完整版本对的查找表,它包含大约600对

我当前的设置看起来像这样。启动时,我使用Jackson从csv文件创建了一个简短的实例列表,并将它们保存在一个单例中:

public static class ShortForm{
    public String fullword;
    public String abbreviation;
}

List<ShortForm> shortForms = new ArrayList<ShortForm>();
//csv code ommited
现在这可以了,但速度很慢。有没有办法加快速度?第一步是加载带有逗号的ShortForm对象,但是我还能做什么呢

======更新 更改了代码,使其以另一种方式工作。将字符串拆分为单词并检查集合,以查看该字符串是否为缩写

    StringBuilder fullFormed = new StringBuilder();
    for (String s: Splitter.on(" ").split(add)){
        if (shortFormMap.containsKey(s))
            fullFormed.append(shortFormMap.get(s));
        else
            fullFormed.append(s);
        fullFormed.append(" ");
    }

    return fullFormed.toString().trim();

测试表明,这比原始方法快13倍以上。干杯,达维康

如果跳过
contains()
part:)

如果跳过
contains()
part:)

可以提高性能的是使用比简单数组更好的数据结构来存储短表单。所有的缩写形式都可以按缩写字母顺序存储。因此,您可以将查找时间从O(N)减少到看起来更像二进制搜索的时间

我以前没有使用过它,但也许标准库的SortedMap完全符合要求,而不是使用自定义对象:

以下是我的想法:

  • 将缩写/完整单词对放入树形图中
  • 将地址标记为单词
  • 检查每个单词是否为树状图中的键
  • 如果是,请更换
  • 将更正后的令牌重新组合为地址

真正能够提高性能的是使用比简单数组更好的数据结构来存储短表单。所有的缩写形式都可以按缩写字母顺序存储。因此,您可以将查找时间从O(N)减少到看起来更像二进制搜索的时间

我以前没有使用过它,但也许标准库的SortedMap完全符合要求,而不是使用自定义对象:

以下是我的想法:

  • 将缩写/完整单词对放入树形图中
  • 将地址标记为单词
  • 检查每个单词是否为树状图中的键
  • 如果是,请更换
  • 将更正后的令牌重新组合为地址

    • 我想我应该用HashMap来实现这一点。关键是缩写,值是完整术语。然后在字符串中搜索逗号,看看逗号前面的文本是否在字典中。您可能可以在一次过程中将所有替换映射到一个字符串中,然后再进行所有替换


      这使得每次查找O(1)总共有O(n)个查找,其中n是找到的缩写的数量,我认为没有更有效的方法。

      我想我应该使用HashMap来实现这一点。关键是缩写,值是完整术语。然后在字符串中搜索逗号,看看逗号前面的文本是否在字典中。您可能可以在一次过程中将所有替换映射到一个字符串中,然后再进行所有替换



      这使得每次查找O(1)总共有O(n)个查找,其中n是找到的缩写的数量,我认为没有更有效的方法。

      由于您有数百万个字符串查找,一种方法是对它们进行索引并进行全文搜索,以获取与缩写匹配的所有地址(我假设地址查找是最慢的部分,因为数量巨大,而不是替换)我正在替换加载中的以提高查询可靠性和速度。不过,你是对的,我可以在加载所有行后批量执行这些操作。可能值得一试。不确定这是否可以提高性能,但不要检查是否包含。只需替换即可。如果它不包含字符串,则不会发生任何事情。因为您有数百万个字符串查找,请继续一种方法是对它们进行索引并进行全文搜索,以获取与缩写匹配的所有地址(我假设地址查找是最慢的部分,因为数量巨大,而不是替换)我正在替换加载中的以提高查询可靠性和速度。不过,你是对的,我可以在加载所有行后分批执行。可能值得一试。不确定这是否可以提高性能,但不要检查是否包含。只需替换即可。如果它不包含字符串,则不会发生任何事情。我猜替换调用包含().Doh.好地方。我猜替换调用包含().Doh.很好。对它们进行排序会有什么帮助?我需要检查它们的全部。查找每个循环的速度会快得多。现在查找每个循环需要600次迭代。在二进制搜索中,一个循环大约需要6次迭代。更好的是,你不需要为此实现任何算法;TreeMap应用程序ears将是您所需的SortedMap的实现,它包含在Java标准库中。等等,我可能误解了您的做法。我以为您是在反其道而行之(检查文本中的每个单词是否在列表中存在缩写)。啊,我以为我一时糊涂了:)这样想吧——现在你正在进行600次全文搜索。这样,您就可以对每个单词进行1次查找+设置/标记化的开销。因此,如果代币的总数相对较少,这是很有意义的。对它们进行排序会有什么帮助?我需要全部检查一下。查找每一个会快得多。现在,一个循环需要600次迭代才能找到每个循环。在二进制搜索中,大约需要6分钟
          StringBuilder fullFormed = new StringBuilder();
          for (String s: Splitter.on(" ").split(add)){
              if (shortFormMap.containsKey(s))
                  fullFormed.append(shortFormMap.get(s));
              else
                  fullFormed.append(s);
              fullFormed.append(" ");
          }
      
          return fullFormed.toString().trim();