【问题标题】:Better alternative to nested loop嵌套循环的更好替代方案
【发布时间】:2018-04-15 00:48:23
【问题描述】:

我目前正在编写一个程序,该程序需要在 String 的 ArrayList 的 ArrayList 中将相似的字符串与 Damerau levenshtein 算法进行比较。现在,我这样做的方式是通过嵌套代码循环:

Damerau d = new Damerau();

for(int i = 0;i<outer.size();i++) {
    System.out.println(i);
    String cstring = outer.get(i).get(5);
    for(ArrayList<String> current : outer) {
        if(d.distance(cstring , current.get(5)) < 30){
            //System.out.println(cstring);
            outer.get(i).set(0, current.get(0));
            break;
        }
    }
}

但这真的很慢,因为 arraylist 由 33000 个字符串 arraylists 组成。

【问题讨论】:

  • 如果您正在从数据库中读取数据,那么不是获取所有数据,而是只提取所需的数据。 SQL 查询比逐行比较要快。如果您不使用 RDBMS,那么我建议您至少使用 sqlite 转储数据并使用查询获取数据。另一件事是使用一些分析器工具并确定哪条线正在消耗越来越多的时间。如果可能,请尝试将数据拆分为较小的列表和独立线程。
  • 您是否对代码进行了基准测试以查看花费最多的时间?一种优化可能是只在外循环中获取一次outer.get(i),而不是在每次内循环迭代中获取它。
  • 如何标记您已经检查的值以跳过它们?如果匹配,您也可以更新current,而不是只设置out.get(i)
  • 如果您在比较相似的字符串,您是否尝试过对数据进行排序?
  • @phflack 算法比较String 中的相似性与String 不相似,所以ZenTen 相似,距离为1。你不能这样排序。

标签: java loops arraylist nested nested-loops


【解决方案1】:

因此,如果我正确理解了您的代码,您可以按照以下方式进行操作:

对于每个外部作为 cstring : 对于每个外部作为当前: levenshtein(cstring,当前)

这意味着您会进行大量不必要的比较。假设您有一个包含字符串[a, b, c] 的列表,那么您正在测试的组合是[aa, ab, ac, ba, bb, bc, ca, cb, cc]。这包括与自身的比较 (aa, bb, cc),始终为 0,以及使用交换参数 (ab,ba,ac,ca,bc,cb) 调用 levenshtein 函数,这些参数始终相同。因此,如果您跳过相同的配对和自我测试,您只需要测试组合ab,ac,bc。通过在 i+1 上启动内部循环,您可以很容易地在代码中实现这一点。

【讨论】:

    猜你喜欢
    • 2015-06-29
    • 1970-01-01
    • 2023-01-17
    • 2021-05-25
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    相关资源
    最近更新 更多