更快速地生成排列

时间:2013-12-05 02:13:18

标签: java string optimization permutation n-gram

我正在研究一个计算两个字符串(A和B)之间命中百分比的程序。为了获得准确的百分比,我将N-Grams与作为字符串A的排列的字符串列表进行匹配。

这是我的代码

public String[] generatePermutations( String name ){

    String[] perms = new String[ calcN(name.length()) ];
    int nameLen = name.length(),
                cnt = 0;


    for(int i = 0; i < name.length(); i++ ){

        nameLen = name.length()-i;
        for( int ii = 0; ii <= i; ii++){
            perms[cnt++] = name.substring( ii, ii + nameLen );
        }
    }
    return perms;
}

参考calcN()在

之下
public int calcN( int n ){
    return ( n * (n+1 )) / 2;
}

给定字符串“ABC”,此方法将生成

  

{“A”,“B”,“C”,“AB”,“BC”,“ABC”}

由于我正在进行此操作数千次(可能是数十万次),有什么方法可以从CPU中挤出一些额外的周期? (除了切换到C ++或C)。一如既往,提前感谢您的建议!

3 个答案:

答案 0 :(得分:1)

该方法的性能优化部分取决于所使用的JVM。例如,在OpenJDK中,子串实现为:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
}

该字符串构造函数是受保护的表单,实现为:

 // Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
     this.value = value;
     this.offset = offset;
     this.count = count;
 }

请注意,这不需要创建一个新值(支持String的char [])。

另一方面,正如Java 7 Performance Tuning Guide中所述,由于内存泄漏而被删除(1000字符长字符串的单字符子字符串被垃圾收集仍然保留支持它的1000个字符串)。 / p>

因此,选择使用哪个jvm会对从子串创建字符串产生重大影响。

根据您的应用程序以及性能的重要性,您可以考虑实现自己的有限版本的String,它重新实现子字符串的偏移和长度实现。

答案 1 :(得分:1)

我知道,我不是在帮助,但我无法抗拒。

Scala one-liner:

(1 to 3).flatMap("ABC".combinations(_))

返回

Vector(A, B, C, AB, AC, BC, ABC)

"ABC".permutations.toList

返回

List(ABC, ACB, BAC, BCA, CAB, CBA)

在JVM上使用Scala非常容易。

答案 2 :(得分:0)

这没什么用,但是我看不到使用cnt,只使用ii