如何使用最少的字符替换次数将字符串转换为回文,以便回文字符串包含给定的单词?

时间:2016-11-05 10:39:00

标签: java string algorithm replace string-algorithm

我们有一个字符串s,包含小写字母(a-z)。我们可以用任何其他角色替换任何角色,我们可以多次这样做。

我们可以从p制作回文字符串s,以便p包含给定的特定字词(即假设linkedin)。现在,我们需要找到将字符串s转换为p所需的最少插入次数。

前 - s = linkedininininin 然后,palindrom字符串p将是linkedinnideknil,结果将是6。

第二个例子(为了更清楚) - s = linkaeiouideknil 然后p = linkedinnideknil,结果将是4,因为我们将a替换为e,将e替换为dou n。{/ p>

我试图通过取s和p的LCS并从s的长度中减去它来解决它。但问题是我如何确保回文保证包含给定的单词(Linkedin)?

请提供您的方法。感谢。

3 个答案:

答案 0 :(得分:1)

假设我理解你的问题,

您可以创建回文,然后在s中替换错误的字母:

String s="linkaeiouideknil";
String p="";
String word="linkedin";
char[] wordC = word.toCharArray();
StringBuilder sb = new StringBuilder();
sb.append(word);
String drow = sb.reverse().toString();
sb.reverse();
sb.append(drow);
String pali=sb.toString();
char[] sC = s.toCharArray();
sC=Arrays.copyOf(sC, pali.length());
sb.delete(0, sb.length());
int counter=0;
for (int i = 0; i < sC.length; i++) {
    if(sC[i]!=pali.charAt(i)){
        sC[i]=pali.charAt(i);
        counter++;
    }
    sb.append(sC[i]);
}
System.out.println(counter);    
p=sb.toString();
System.out.println(p);

运行时的输出为4.

答案 1 :(得分:1)

我会同时迭代弦乐和回文;插入输入字符串中不存在的字符,并在有下一个可用字符时替换子字符串:

public int palindromify(String pal, String read) {
    StringBuilder sb = new StringBuilder(read);
    int insertions = 0; //track insertions
    int palIndex = 0; //our progress through the palindrome
    //caches characters we know aren't further in the input, saves time
    Set<Character> none = new HashSet<>();
    boolean outOfInput = false;
    for (int i = 0;; i++) {
        if (i >= sb.length()) {
            outOfInput = true; //if we run out of input, we know we have to append remainder
            break;
        }
        if (palIndex >= pal.length()) {
            sb.delete(i, sb.length()); //remove remainder, we're out of palindrome
            break;
        }
        char curr = pal.charAt(palIndex++); //increment palindrome
        if (sb.charAt(i) != curr) {
            //perform lookahead
            boolean found = false;
            if (!none.contains(curr)) { //only search a missing char once
                for (int w = i + 1; w < sb.length(); w++) {
                    if (sb.charAt(w) == curr) {
                        sb.replace(i, w + 1, "" + curr); //replace up to our lookahead
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    none.add(curr);
                }
            }
            if (!found) {
                //simply insert our character, later ones are useful for others
                sb.insert(i, curr);
                insertions++; //this was an insertion, one of our counted values
            }
        }
    }
    //if we ran out of input, append the rest of palindrome
    return insertions + (outOfInput ? pal.length() - sb.length() : 0);
}

这可以节省大量复制/迭代/不必要的工作,并且应该确保最大迭代量是读取回文的长度(或输入的长度,以较短者为准)

因此在致电:

palindromify("linkedinnideknil", "linkedinininin"); //prints '4'

创建实际的回文非常容易,而且工作要少得多:

String s = /* some value */;
s += new StringBuilder(s).reverse();

编辑:不适用于某些边缘情况,修复。

答案 2 :(得分:0)

我首先要创建你想要将你的字符串转换成的回文。接下来,计算从原始字符串到您创建的回文的编辑距离,其中您的编辑正在替换字符串中的字符:无插入或删除。代码看起来像

def minReplacements(original, palindrome, m, n):
    # base case:  we're finished processing either string so we're done
    if (m == 0 or n == 0):
        return 0

    # The characters in the string match so find out how many replacements are
    # required for the remaining characters in the strings.
    if (original[m-1] == palindrome[n-1]):
        return minReplacements(origininal, palindrome, m-1, n-1)

    # Recurse on replacing a character in the original string
    # with a character in the palindrome string
    return 1 + minReplacements(origininal, palindrome, m-1, n-1)

另一方面,如果您想知道将原始字符串转换为回文字符串需要多少字符替换,插入或删除,请使用以下代码更改上面代码的最后一行:

    return 1 + min(minReplacements(origininal, palindrome, m, n-1),   # insert character
                   minReplacements(origininal, palindrome, m-1, n-1), # replace character
                   minReplacements(origininal, palindrome, m-1, n))   # delete character

代码看起来像:

def minReplacements(original, palindrome, m, n):
    # base case:  we're finished processing either string so we're done
    if (m == 0):  # done processing original string
        return n  # return the number of characters left in palindrome
    if (n == 0):  # done processing palindrome
        return m  # return the number of characters left in the original string

    # The characters in the string match so find out how many edits are
    # required for the remaining characters in the strings.
    if (original[m] == palindrome[n]):
        return minReplacements(origininal, palindrome, m-1, n-1)

    # Recurse on editing a character in the original string
    # with a character in the palindrome string
    return 1 + min(minReplacements(origininal, palindrome, m, n-1),   # insert character
                   minReplacements(origininal, palindrome, m-1, n-1), # replace character
                   minReplacements(origininal, palindrome, m-1, n))   # delete character