private int levenshtein(String a, String b, int swap, int sub, int add,
            int del) {
        int alen = a.length();
        int blen = b.length();
        int[][] dp = new int[3][blen + 1];
        for (int i = 0; i <= blen; ++i) {
            dp[1][i] = i;
        }
        for (int i = 1; i <= alen; ++i) {
            dp[0][0] = i;
            for (int j = 1; j <= blen; ++j) {
                dp[0][j] = dp[1][j - 1]
                        + (a.charAt(i - 1) == b.charAt(j - 1) ? 0 : sub);
                if (i >= 2 && j >= 2 && a.charAt(i - 1) != b.charAt(j - 1)
                        && a.charAt(i - 2) == b.charAt(j - 1)
                        && a.charAt(i - 1) == b.charAt(j - 2)) {
                    dp[0][j] = Math.min(dp[0][j], dp[2][j - 2] + swap);
                }
                dp[0][j] = Math.min(dp[0][j],
                        Math.min(dp[1][j] + del, dp[0][j - 1] + add));
            }
            int[] temp = dp[2];
            dp[2] = dp[1];
            dp[1] = dp[0];
            dp[0] = temp;
        }
        return dp[1][blen];
    }