如何找到给定字符串中最长的回文?

发布于 2024-08-29 17:56:49 字数 489 浏览 5 评论 0原文

可能的重复:
编写一个返回最长回文的函数在给定的字符串中

我知道如何在 O(n^2) 内做到这一点。但似乎存在更好的解决方案。

我发现 this,并且有一个指向 O(n) 答案的链接,但它是用 Haskell 编写的,我不清楚。

如果能得到 c# 或类似的答案那就太好了。

Possible Duplicate:
Write a function that returns the longest palindrome in a given string

I know how to do this in O(n^2). But it seems like there exist a better solution.

I've found this, and there is a link to O(n) answer, but it's written in Haskell and not clear for me.

It would be great to get an answer in c# or similar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凤舞天涯 2024-09-05 17:56:49

我找到了解决方案的明确解释 此处。感谢贾斯汀提供此链接。

在那里您可以找到该算法的 Python 和 Java 实现(C++ 实现包含错误)。

这里是 C# 实现,它只是这些算法的翻译。

public static int LongestPalindrome(string seq)
    {
        int Longest = 0;
        List<int> l = new List<int>();
        int i = 0;
        int palLen = 0;
        int s = 0;
        int e = 0;
        while (i<seq.Length)
        {
            if (i > palLen && seq[i-palLen-1] == seq[i])
            {
                palLen += 2;
                i += 1;
                continue;
            }
            l.Add(palLen);
            Longest = Math.Max(Longest, palLen);
            s = l.Count - 2;
            e = s - palLen;
            bool found = false;
            for (int j = s; j > e; j--)
            {
                int d = j - e - 1;
                if (l[j] == d)
                {
                    palLen = d;
                    found = true;
                    break;
                }
                l.Add(Math.Min(d, l[j]));
            }
            if (!found)
            {
                palLen = 1;
                i += 1;
            }
        }
        l.Add(palLen);
        Longest = Math.Max(Longest, palLen);
        return Longest;
    }

I've found clear explanation of the solution here. Thanks to Justin for this link.

There you can find Python and Java implementations of the algorithm (C++ implementation contains errors).

And here is C# implementation that is just a translation of those algorithms.

public static int LongestPalindrome(string seq)
    {
        int Longest = 0;
        List<int> l = new List<int>();
        int i = 0;
        int palLen = 0;
        int s = 0;
        int e = 0;
        while (i<seq.Length)
        {
            if (i > palLen && seq[i-palLen-1] == seq[i])
            {
                palLen += 2;
                i += 1;
                continue;
            }
            l.Add(palLen);
            Longest = Math.Max(Longest, palLen);
            s = l.Count - 2;
            e = s - palLen;
            bool found = false;
            for (int j = s; j > e; j--)
            {
                int d = j - e - 1;
                if (l[j] == d)
                {
                    palLen = d;
                    found = true;
                    break;
                }
                l.Add(Math.Min(d, l[j]));
            }
            if (!found)
            {
                palLen = 1;
                i += 1;
            }
        }
        l.Add(palLen);
        Longest = Math.Max(Longest, palLen);
        return Longest;
    }
朕就是辣么酷 2024-09-05 17:56:49

这是它的 java 版本:

public static int LongestPalindrome(String seq) {
    int Longest = 0;
    List<Integer> l = new ArrayList<Integer>();
    int i = 0;
    int palLen = 0;
    int s = 0;
    int e = 0;

    while (i < seq.length()) {
        if (i > palLen && seq.charAt(i - palLen - 1) == seq.charAt(i)) {
            palLen += 2;
            i += 1;
            continue;
        }
        l.add(palLen);
        Longest = Math.max(Longest, palLen);
        s = l.size() - 2;
        e = s - palLen;
        boolean found = false;
        for (int j = s; j > e; j--) {
            int d = j - e - 1;
            if (l.get(j) == d) {
                palLen = d;
                found = true;
                break;
            }
            l.add(Math.min(d, l.get(j)));
        }
        if (!found) {
            palLen = 1;
            i += 1;
        }
    }
    l.add(palLen);
    Longest = Math.max(Longest, palLen);
    return Longest;
}

And this is its java version:

public static int LongestPalindrome(String seq) {
    int Longest = 0;
    List<Integer> l = new ArrayList<Integer>();
    int i = 0;
    int palLen = 0;
    int s = 0;
    int e = 0;

    while (i < seq.length()) {
        if (i > palLen && seq.charAt(i - palLen - 1) == seq.charAt(i)) {
            palLen += 2;
            i += 1;
            continue;
        }
        l.add(palLen);
        Longest = Math.max(Longest, palLen);
        s = l.size() - 2;
        e = s - palLen;
        boolean found = false;
        for (int j = s; j > e; j--) {
            int d = j - e - 1;
            if (l.get(j) == d) {
                palLen = d;
                found = true;
                break;
            }
            l.add(Math.min(d, l.get(j)));
        }
        if (!found) {
            palLen = 1;
            i += 1;
        }
    }
    l.add(palLen);
    Longest = Math.max(Longest, palLen);
    return Longest;
}
卸妝后依然美 2024-09-05 17:56:49
public static string GetMaxPalindromeString(string testingString)
{
    int stringLength = testingString.Length;
    int maxPalindromeStringLength = 0;
    int maxPalindromeStringStartIndex = 0;

    for (int i = 0; i < stringLength; i++)
    {
        int currentCharIndex = i;

        for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
        {
            if (lastCharIndex - currentCharIndex + 1 < maxPalindromeStringLength)
            {
                break;
            }

            bool isPalindrome = true;

            if (testingString[currentCharIndex] != testingString[lastCharIndex])
            {
                continue;
            }
            else
            {
                int matchedCharIndexFromEnd = lastCharIndex - 1;

                for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < matchedCharIndexFromEnd; nextCharIndex++)
                {
                    if (testingString[nextCharIndex] != testingString[matchedCharIndexFromEnd])
                    {
                        isPalindrome = false;
                        break;
                    }
                    matchedCharIndexFromEnd--;
                }
            }

            if (isPalindrome)
            {
                if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
                {
                    maxPalindromeStringStartIndex = currentCharIndex;
                    maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
                }
                break;
            }
        }
    }

    if(maxPalindromeStringLength>0)
    {
        return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
    }

    return null;

}
public static string GetMaxPalindromeString(string testingString)
{
    int stringLength = testingString.Length;
    int maxPalindromeStringLength = 0;
    int maxPalindromeStringStartIndex = 0;

    for (int i = 0; i < stringLength; i++)
    {
        int currentCharIndex = i;

        for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
        {
            if (lastCharIndex - currentCharIndex + 1 < maxPalindromeStringLength)
            {
                break;
            }

            bool isPalindrome = true;

            if (testingString[currentCharIndex] != testingString[lastCharIndex])
            {
                continue;
            }
            else
            {
                int matchedCharIndexFromEnd = lastCharIndex - 1;

                for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < matchedCharIndexFromEnd; nextCharIndex++)
                {
                    if (testingString[nextCharIndex] != testingString[matchedCharIndexFromEnd])
                    {
                        isPalindrome = false;
                        break;
                    }
                    matchedCharIndexFromEnd--;
                }
            }

            if (isPalindrome)
            {
                if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
                {
                    maxPalindromeStringStartIndex = currentCharIndex;
                    maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
                }
                break;
            }
        }
    }

    if(maxPalindromeStringLength>0)
    {
        return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
    }

    return null;

}
深府石板幽径 2024-09-05 17:56:49

C#

首先,我搜索偶数长度的回文。然后我搜索奇数长度的回文。当它找到回文时,它会确定长度并相应地设置最大长度。平均情况复杂度是线性的。

        protected static int LongestPalindrome(string str)
    {
        int i = 0; 
        int j = 1;
        int oldJ = 1;
        int intMax = 1;
        int intCount = 0;

        if (str.Length == 0) return 0;
        if (str.Length == 1) return 1;

        int[] intDistance = new int[2] {0,1};

        for( int k = 0; k < intDistance.Length; k++ ){

            j = 1 + intDistance[k];
            oldJ = j;
            intCount = 0;
            i = 0;

            while (j < str.Length)
            {


                if (str[i].Equals(str[j]))
                {
                    oldJ = j;
                    intCount = 2 + intDistance[k];
                    i--;
                    j++;
                    while (i >= 0 && j < str.Length)
                    {
                        if (str[i].Equals(str[j]))
                        {
                            intCount += 2;
                            i--;
                            j++;
                            continue;
                        }
                        else
                        {
                            break;
                        }

                    }
                    intMax = getMax(intMax, intCount);
                    j = oldJ + 1;
                    i = j - 1 - intDistance[k];

                }
                else
                {
                    i++;
                    j++;
                }
            }
        }

        return intMax;
    }

    protected static int getMax(int a, int b)
    {
        if (a > b) return a; return b;
    }

C#

First I search for even length palindromes. Then I search for odd length palindromes. When it finds a palindrome, it determines the length and sets the max length accordingly. The average case complexity for this is linear.

        protected static int LongestPalindrome(string str)
    {
        int i = 0; 
        int j = 1;
        int oldJ = 1;
        int intMax = 1;
        int intCount = 0;

        if (str.Length == 0) return 0;
        if (str.Length == 1) return 1;

        int[] intDistance = new int[2] {0,1};

        for( int k = 0; k < intDistance.Length; k++ ){

            j = 1 + intDistance[k];
            oldJ = j;
            intCount = 0;
            i = 0;

            while (j < str.Length)
            {


                if (str[i].Equals(str[j]))
                {
                    oldJ = j;
                    intCount = 2 + intDistance[k];
                    i--;
                    j++;
                    while (i >= 0 && j < str.Length)
                    {
                        if (str[i].Equals(str[j]))
                        {
                            intCount += 2;
                            i--;
                            j++;
                            continue;
                        }
                        else
                        {
                            break;
                        }

                    }
                    intMax = getMax(intMax, intCount);
                    j = oldJ + 1;
                    i = j - 1 - intDistance[k];

                }
                else
                {
                    i++;
                    j++;
                }
            }
        }

        return intMax;
    }

    protected static int getMax(int a, int b)
    {
        if (a > b) return a; return b;
    }
朦胧时间 2024-09-05 17:56:49

最近我在面试时写了以下代码......

    public string FindMaxLengthPalindrome(string s)
    {
        string maxLengthPalindrome = "";

        if (s == null) return s;

        int len = s.Length;

        for(int i = 0; i < len; i++)
        {
            for (int j = 0; j < len - i; j++)
            {
                bool found = true;
                for (int k = j; k < (len - j) / 2; k++)
                {
                    if (s[k] != s[len - (k - j + 1)])
                    {
                        found = false;
                        break;
                    }
                }

                if (found)
                {
                    if (len - j > maxLengthPalindrome.Length)
                        maxLengthPalindrome = s.Substring(j, len - j); 
                }

                if(maxLengthPalindrome.Length >= (len - (i + j)))
                    break;
            }

            if (maxLengthPalindrome.Length >= (len - i))
                break;
        }

        return maxLengthPalindrome;
    }

Recently I wrote following code during interview...

    public string FindMaxLengthPalindrome(string s)
    {
        string maxLengthPalindrome = "";

        if (s == null) return s;

        int len = s.Length;

        for(int i = 0; i < len; i++)
        {
            for (int j = 0; j < len - i; j++)
            {
                bool found = true;
                for (int k = j; k < (len - j) / 2; k++)
                {
                    if (s[k] != s[len - (k - j + 1)])
                    {
                        found = false;
                        break;
                    }
                }

                if (found)
                {
                    if (len - j > maxLengthPalindrome.Length)
                        maxLengthPalindrome = s.Substring(j, len - j); 
                }

                if(maxLengthPalindrome.Length >= (len - (i + j)))
                    break;
            }

            if (maxLengthPalindrome.Length >= (len - i))
                break;
        }

        return maxLengthPalindrome;
    }
北音执念 2024-09-05 17:56:49

我在接受采访的时候就被问到了这个问题。

不幸的是,当我回到家时我才发现。

public static string GetMaxPalindromeString(string testingString)
    {
        int stringLength = testingString.Length;
        int maxPalindromeStringLength = 0;
        int maxPalindromeStringStartIndex = 0;

        for (int i = 0; i < testingString.Length; i++)
        {
            int currentCharIndex = i;

            for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
            {
                bool isPalindrome = true;

                if (testingString[currentCharIndex] != testingString[lastCharIndex])
                {
                    continue;
                }

                for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < lastCharIndex / 2; nextCharIndex++)
                {
                    if (testingString[nextCharIndex] != testingString[lastCharIndex - 1])
                    {
                        isPalindrome = false;
                        break;
                    }
                }

                if (isPalindrome)
                {
                    if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
                    {
                        maxPalindromeStringStartIndex = currentCharIndex;
                        maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
                    }
                }
                break;
            }
        }

        return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
    }

I got this question when i took an interview.

I found out when i was back home, unfortunately.

public static string GetMaxPalindromeString(string testingString)
    {
        int stringLength = testingString.Length;
        int maxPalindromeStringLength = 0;
        int maxPalindromeStringStartIndex = 0;

        for (int i = 0; i < testingString.Length; i++)
        {
            int currentCharIndex = i;

            for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
            {
                bool isPalindrome = true;

                if (testingString[currentCharIndex] != testingString[lastCharIndex])
                {
                    continue;
                }

                for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < lastCharIndex / 2; nextCharIndex++)
                {
                    if (testingString[nextCharIndex] != testingString[lastCharIndex - 1])
                    {
                        isPalindrome = false;
                        break;
                    }
                }

                if (isPalindrome)
                {
                    if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
                    {
                        maxPalindromeStringStartIndex = currentCharIndex;
                        maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
                    }
                }
                break;
            }
        }

        return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文