NASU41 / AtCoderLibraryForJava

Creative Commons Zero v1.0 Universal
76 stars 21 forks source link

String - Suffix Array #4

Open m1zz1y opened 4 years ago

uwi commented 4 years ago

Suffix Arrayの実装のうち、NaiveとDoublingについて、以下の懸念点があります。

suisen-cp commented 4 years ago

int[] のソート用に MergeSort のライブラリを持っているので提供できますが, 10 や 40 程度であれば挿入ソートの方が速いと思われます. (挿入ソートも持っているので提供できます)

uwi commented 4 years ago

@suisen-cp コードもらえますか?パフォーマンス測ってみます。

suisen-cp commented 4 years ago

直接貼ります

class SortUsingComparator {
    static void insertionsortUsingComparator(int[] a, java.util.function.IntBinaryOperator comparator) {
        final int n = a.length;
        for (int i = 1; i < n; i++) {
            final int tmp = a[i];
            if (comparator.applyAsInt(a[i - 1], tmp) > 0) {
                int j = i;
                do {
                    a[j] = a[j - 1];
                    j--;
                } while (j > 0 && comparator.applyAsInt(a[j - 1], tmp) > 0);
                a[j] = tmp;
            }
        }
    }

    static void mergesortUsingComparator(int[] a, java.util.function.IntBinaryOperator comparator) {
        final int n = a.length;
        final int[] work = new int[n];
        for (int block = 1; block <= n; block <<= 1) {
            final int block2 = block << 1;
            for (int l = 0, max = n - block; l < max; l += block2) {
                int m = l + block;
                int r = Math.min(l + block2, n);
                System.arraycopy(a, l, work, 0, block);
                for (int i = l, wi = 0, ti = m;; i++) {
                    if (ti == r) {
                        System.arraycopy(work, wi, a, i, block - wi);
                        break;
                    }
                    if (comparator.applyAsInt(work[wi], a[ti]) > 0) {
                        a[i] = a[ti++];
                    } else {
                        a[i] = work[wi++];
                        if (wi == block) break;
                    }
                }
            }
        }
    }
}
uwi commented 4 years ago
uwi commented 3 years ago

手元でランダムケースとinsertionSortの最悪ケースで調べてTHRESHOLDを調整した結果、 saNaiveは50未満, saDoubling使わずという結果になりました。

テストコード等もできればリポジトリに上げたいですが、今その場はないようですね。