【问题标题】:How to find the longest palindrome in a given string? [duplicate]如何在给定字符串中找到最长的回文? [复制]
【发布时间】:2010-04-20 16:49:51
【问题描述】:

可能重复:
Write a function that returns the longest palindrome in a given string

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

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

如果能在 c# 或类似语言中得到答案,那就太好了。

【问题讨论】:

  • 这是另一个问题的完全副本,即您自己链接到的问题。如果您不明白那里的答案,请在此处发表评论,不要打开新问题! (对于它的价值,即使您完全忽略 Haskell 代码,我认为链接的博客文章也有相当清晰的解释。)
  • 没有提到应该用哪种编程语言编写
  • 是的,好点;我一直觉得 Stack Overflow 缺乏让多人问同一个问题的机制……如果你有足够的声誉,我想你可以编辑问题并希望它带来更好的答案,但这并不理想。
  • 我认为最好的方法是从您对链接的分析开始,并尝试构建算法的“伪代码”表示,突出显示您无法解释的部分博客文章的散文......事实上,如果你这样做,我会投票重新开放......在 C# 与 Haskell 中要求这个只是另一种毫无意义的翻译,有一个普遍的表示有很多价值。
  • 试试这个链接:akalin.cx/2007/11/28/…。它有 Python 代码,你可能更容易理解。它还包含可能有帮助的算法的替代解释。

标签: c# algorithm palindrome


【解决方案1】:

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

在那里你可以找到算法的 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;
    }

【讨论】:

    【解决方案2】:

    这是它的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;
    }
    

    【讨论】:

      【解决方案3】:
      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;
      
      }
      

      【讨论】:

        【解决方案4】:

        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;
            }
        

        【讨论】:

        • 请添加解释为什么会这样
        【解决方案5】:

        最近在面试的时候写了如下代码...

            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;
            }
        

        【讨论】:

          【解决方案6】:

          我在面试的时候遇到了这个问题。

          不幸的是,我是在回家的时候发现的。

          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);
              }
          

          【讨论】:

          • 为了 googlers 的利益而发布尸体:这个答案是不正确的。使用字符串“abcdedcbax”运行它会返回“dedcbax”。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-30
          相关资源
          最近更新 更多