Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 优化Jaro-Winkler算法_Java_Algorithm_Optimization_Jaro Winkler - Fatal编程技术网

Java 优化Jaro-Winkler算法

Java 优化Jaro-Winkler算法,java,algorithm,optimization,jaro-winkler,Java,Algorithm,Optimization,Jaro Winkler,我从网站上获得了Jaro Winkler算法的代码。我需要跑150000次才能获得差异之间的距离。这需要很长时间,因为我在安卓移动设备上运行 它能更优化吗 public class Jaro { /** * gets the similarity of the two strings using Jaro distance. * * @param string1 the first input string * @param string2 the

我从网站上获得了Jaro Winkler算法的代码。我需要跑150000次才能获得差异之间的距离。这需要很长时间,因为我在安卓移动设备上运行

它能更优化吗

public class Jaro {
    /**
     * gets the similarity of the two strings using Jaro distance.
     *
     * @param string1 the first input string
     * @param string2 the second input string
     * @return a value between 0-1 of the similarity
     */
    public float getSimilarity(final String string1, final String string2) {

        //get half the length of the string rounded up - (this is the distance used for acceptable transpositions)
        final int halflen = ((Math.min(string1.length(), string2.length())) / 2) + ((Math.min(string1.length(), string2.length())) % 2);

        //get common characters
        final StringBuffer common1 = getCommonCharacters(string1, string2, halflen);
        final StringBuffer common2 = getCommonCharacters(string2, string1, halflen);

        //check for zero in common
        if (common1.length() == 0 || common2.length() == 0) {
            return 0.0f;
        }

        //check for same length common strings returning 0.0f is not the same
        if (common1.length() != common2.length()) {
            return 0.0f;
        }

        //get the number of transpositions
        int transpositions = 0;
        int n=common1.length();
        for (int i = 0; i < n; i++) {
            if (common1.charAt(i) != common2.charAt(i))
                transpositions++;
        }
        transpositions /= 2.0f;

        //calculate jaro metric
        return (common1.length() / ((float) string1.length()) +
                common2.length() / ((float) string2.length()) +
                (common1.length() - transpositions) / ((float) common1.length())) / 3.0f;
    }

    /**
     * returns a string buffer of characters from string1 within string2 if they are of a given
     * distance seperation from the position in string1.
     *
     * @param string1
     * @param string2
     * @param distanceSep
     * @return a string buffer of characters from string1 within string2 if they are of a given
     *         distance seperation from the position in string1
     */
    private static StringBuffer getCommonCharacters(final String string1, final String string2, final int distanceSep) {
        //create a return buffer of characters
        final StringBuffer returnCommons = new StringBuffer();
        //create a copy of string2 for processing
        final StringBuffer copy = new StringBuffer(string2);
        //iterate over string1
        int n=string1.length();
        int m=string2.length();
        for (int i = 0; i < n; i++) {
            final char ch = string1.charAt(i);
            //set boolean for quick loop exit if found
            boolean foundIt = false;
            //compare char with range of characters to either side

            for (int j = Math.max(0, i - distanceSep); !foundIt && j < Math.min(i + distanceSep, m - 1); j++) {
                //check if found
                if (copy.charAt(j) == ch) {
                    foundIt = true;
                    //append character found
                    returnCommons.append(ch);
                    //alter copied string2 for processing
                    copy.setCharAt(j, (char)0);
                }
            }
        }
        return returnCommons;
    }
}

如果您要进行测试并需要示例,以便不破坏脚本,您将在另一个python优化线程中找到它

是的,但您不会喜欢它。用构造函数中分配的字符数组替换所有那些
new
StringBuffers,并使用整数索引跟踪其中的内容

会给你一些味道

  • 尽量避免getCommonCharacters循环中的两个嵌套循环。
    建议:将较小字符串中的所有字符存储在某种类型的映射中(java有一些),其中键是字符,值是位置,这样您仍然可以计算距离,无论它们是否相同。我不太了解算法,但我认为这是可行的
  • <> LI>除了这一点和BGuulyes的答案之外,我真的看不到除了BIT之类的东西之外的进一步优化。如果这是非常关键的,考虑在C?中重写这一部分。
    我知道这个问题可能已经解决了一段时间,但我想谈谈算法本身。将字符串与自身进行比较时,结果是1/| string | off。当比较稍有不同的值时,值也会更低

    解决方法是在getCommonCharacters方法中,将内部for语句中的“m-1”调整为“m”。然后,代码就像一个符咒:)


    另请参阅一些示例。

    我不太了解Android以及它如何与数据库协同工作。WP7有(将有:)个SQL CE。下一步通常是处理数据。添加字符串长度并限制比较。在两列上添加索引,然后按长度和值排序。长度索引也应该进行排序。我让它在一台旧服务器上运行,在0.5秒内,有150000个医学术语给我提供建议和拼写检查,用户几乎不会注意到它,尤其是在一个单独的线程上运行时

    我打算在博客上写很长时间(比如2年:),因为有需要。但我终于设法写了一些关于它的文字,并提供了一些提示。请在这里查看:


    虽然是针对微软平台的,但一般原则是一样的

    是的,这可以做得更快。首先,您根本不需要StringBuffers。另一方面,不需要单独的循环来计算换位


    你可以找到,而且应该快得多。它在Apache2.0许可证下。

    与使用GetCommonCharacters方法返回公共字符不同,使用两个数组来保持匹配,与这里的C版本类似

    /*计算匹配字符*/
    对于(i=0;i
    另一个优化是为每个字符串预先计算位掩码。 使用该选项,检查第一个字符串上的当前字符是否存在于第二个字符串上。这可以使用高效的位操作来完成


    这将跳过计算最大/最小值和循环丢失的字符。

    我对此表示怀疑,但我运行了一些测试,似乎char数组的速度实际上是StringBuffer的十倍。如果要避免使用实际的字符数组,StringBuilder的速度只有字符数组的两倍。
    jaro= new Jaro();
    
    /*Calculate matching characters*/
    for (i = 0; i < al; i++) {
        for (j = max(i - range, 0), l = min(i + range + 1, sl); j < l; j++) {
            if (a[i] == s[j] && !sflags[j]) {
                sflags[j] = 1;
                aflags[i] = 1;
                m++;
                break;
            }
        }
    }