在字符串中找到最大的subpalindrome

时间:2012-06-29 14:25:31

标签: java

我正试图在Java中找到一个subpalindrome。但是下面的代码没有提供正确的输出。

public static void main(String[] args)
{
    Scanner in = new Scanner(System.in);
    in.useDelimiter("\n");
    String text = in.next();
    int start = 0;
    int end = 0;

    int i = 0;
    int j = 0;
    while(i <= text.length())
    {
        j = i+1;
        while(j < text.length())
        {
            if(text.substring(i, j).equals(reverse(text.substring(i, j))))
            {
                if(j-i > end-start)
                {
                    start = i; end = j;
                }   
            }
            j++;
        }
        i++;
    }
    System.out.println(start + " : " + end);
}
static String reverse(String s)
{
    return new StringBuffer(s).reverse().toString();
}

示例输出:

apros tda adda
7 : 12
after the ostso
11 : 14
att feref
5 : 8

以上所有都是错误的。

PS:我知道这不是一种有效的算法。

3 个答案:

答案 0 :(得分:0)

有两个问题:

1:我在上面评论中提到的那个:

if(j-i > end-start) {
    start = i;
    end = j;
}

2:让j一路走到文本末尾:

while(j <= text.length())

这是另一种可能性,既然您已经修复了代码,我可以为您提供另一种更优化的解决方案。找到最大的回文基本上是找到一个字符串之间最常见的单词,反之亦然。所以从反转字符串开始(即text2)。迭代文本(i),然后有一个代表减少长度的子迭代(从text.length() - i下降到0.如果你在text2中找到当前单词,那么你找到了一个回文。你只是需要评估它是否是最大的一个。

一个明显的额外优化是,如果您已经找到了回文,则长度的子迭代不需要降至零。

    String text = "absoopoo";       
    String text2 = new StringBuffer(text).reverse().toString();

    int start = 0;
    int end = -1;

    for(int i=0; i<text.length(); i++) {
        for(int length=text.length()-i; length > (end-start); length--) {
            String sub = text.substring(i, i+length);
            if(text2.indexOf(sub) >= 0) {
                start = i;
                end = start+length;
            }
        }
    }

    System.out.println(start + " : " + end+ " => "+text.substring(start, end));

答案 1 :(得分:0)

终于搞定了。

public static void main(String[] args)
{
    Scanner in = new Scanner(System.in);
    in.useDelimiter("\n");
    String text = in.next();

    int start = 0;
    int end = 0;

    int i = 0;
    int j = 0;
    while(i < text.length())
    {
        j = i;
        while(j <= text.length())
        {
            if(text.substring(i, j).equals(reverse(text.substring(i, j))))
            {
                if(j-i > 1 && j-i > end-start)
                {
                    start = i; 
                    end = j;
                }   
            }
            j++;
        }
        i++;
    }
    System.out.println(start + " : " + (end-1));
}
static String reverse(String s)
{
    return new StringBuffer(s).reverse().toString();
}

这是一个更优化的版本。这基于this

public static void main(String[] args)
{
    Scanner in = new Scanner(System.in);
    in.useDelimiter("\n");
    char[] text = in.next().toCharArray();

    int start = 0;
    int end = 0;
    ArrayList<Integer[]> list = new ArrayList<Integer[]>();
    for( ;start<text.length; start++)
    {
        for(end=start; end<=start+1; end++)
        {
            list.add(grow(text, start, end));
        }
    }
    for(Integer[] v: list)
        System.out.println(v[0] +" : "+v[1]);
    findmax(list);
}
static Integer[] grow(char[] text, int start, int end)
{
    while(start>0 && end < text.length && text[start-1]==text[end])
    {
        start--;
        end++;
    }
    return new Integer[]{start, end};
}
static void findmax(ArrayList<Integer[]> list)
{
    int i=0; int j=0;
    for(Integer[] v: list)
    {
        if(v[1]-v[0]>j-i)
        {
            i = v[0];
            j = v[1];
        }
    }
    System.out.println(i+" "+j);
}

答案 2 :(得分:0)

让我们知道您是否需要(如果它有良好的表现):

/** Transmitted max size between to parses */
static int maxSize = 0;

/**
 * Said if the String is a palindrome.
 * 
 * @param s
 *            sentence to parse.
 */
static void singlePalindrome(final String s) {

    System.out.println("singlePalindrome: " + s);
    final char[] word = s.toCharArray();
    final int t = word.length;
    boolean ok = true;
    for (int i = t / 2; i > 0; i--) {

        if (word[i - 1] != word[word.length - i]) {

            ok = false;
            break;
        }

        System.out.println((i - 1) + ":" + word[i - 1] + "\t" + (t - i)
            + ":" + word[t - i]);
    }

    System.out.println("It is " + (true == ok ? "" : "NOT ")
        + "a palindrome.");
}

/**
 * Find all palindromes included anywhere in a sentence, with two search
 * phases from left to right and right to left. Then keep the biggest one *
 * 
 * @param sentence
 *            to parse
 * @param len
 *            minimal size of palindrome(s) to find.
 */
static void palindromeNested(final String sentence, final int len) {
    System.out.println(len + " = minimal size for palindromeNested(..): "
        + sentence);
    int debS = 2;
    String max = null;

    while (debS <= sentence.length()) {

        int i = debS / 2;
        int cpt = 0;
        for (; i <= debS; i++) {
            ++cpt;
            if (sentence.charAt(i) == sentence.charAt(debS - i)) {
                if (cpt >= len) {
                    final String sTmp = (i > debS - i) //
                        ? sentence.substring(debS - i, i + 1) //
                        : sentence.substring(i, debS - i + 1);

                    final int maxTmp = sTmp.length();
                    if (maxTmp > maxSize) {
                        maxSize = maxTmp;
                        max = sTmp;
                        System.out.println(maxTmp + "\t" + max);
                    }

                    // System.out.format("%4d:%-4d %d :: %d %s,\n", i, debS
                    // - i, cpt, maxTmp, sTmp);
                }

                continue;
            }

            break;
        }

        debS++;         
    }

    System.out.println("Result: " + max);

}

/** @param args */
public static void main(final String[] args) {

    singlePalindrome("abccdccba");// "abccddccba" works
    System.out.println("============================");

    // "baabcc dd ccbaabiib" works like "baabcc d ccbaabiib" (odd problem)
    final String words = "baabcc d ccbaabi o iba ab";
    palindromeNested(new StringBuilder(words).reverse().toString(), 3); // 3carsMini
    System.out.println("----------------------------");

    palindromeNested(words, maxSize / 2); // the max found in first
    System.out.println("============================");

}

}

输出:

singlePalindrome:abccdccba
3:c 5:c
2:c 6:c
1:b 7:b
0:a 8:a
这是一个回文 ============================
3 = palindrome的最小尺寸嵌套(..):ba abi o ibaabcc d ccbaab
5 ba ab
7 bi o ib
9 abi o iba
结果:abi o iba
----------------------------
4 =最小尺寸的回文嵌套(..):baabcc d ccbaabi o iba ab
11 abcc d ccba
13 aabcc d ccbaa
15 baabcc d ccbaab
结果:baabcc d ccbaab
============================