如何检查给定的字符串是否是回文?

时间:2020-03-05 18:50:05  来源:igfitidea点击:

定义:

回文词是单词,词组,数字或者单元的其他序列,具有沿任一方向读取相同内容的特性

如何检查给定的字符串是否是回文?

这是前一段时间的FAIQ(常见访谈问题)之一,但大部分使用C。

寻找任何可能的语言解决方案。

解决方案

回答

boolean isPalindrome(String str1) {
  //first strip out punctuation and spaces
  String stripped = str1.replaceAll("[^a-zA-Z0-9]", "");
  return stripped.equalsIgnoreCase((new StringBuilder(stripped)).reverse().toString());
}

Java版本

回答

语言不可知元代码然后...

rev = StringReverse(originalString)
return ( rev == originalString );

回答

这是我在C#中的解决方案

static bool isPalindrome(string s)
{
    string allowedChars = "abcdefghijklmnopqrstuvwxyz"+
        "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string compareString = String.Empty;
    string rev = string.Empty;

    for (int i = 0; i <= s.Length - 1; i++)
    {
        char c = s[i];

        if (allowedChars.IndexOf(c) > -1)
        {
            compareString += c;
        }
    }

    for (int i = compareString.Length - 1; i >= 0; i--)
    {
        char c = compareString[i];
        rev += c;
    }

    return rev.Equals(compareString, 
        StringComparison.CurrentCultureIgnoreCase);
}

回答

Delphi

function IsPalindrome(const s: string): boolean;
var
  i, j: integer;
begin
  Result := false;
  j := Length(s);
  for i := 1 to Length(s) div 2 do begin
    if s[i] <> s[j] then
      Exit;
    Dec(j);
  end;
  Result := true;
end;

回答

未优化的Python:

>>> def is_palindrome(s):
...     return s == s[::-1]

回答

这是一种python方式。注意:这并不是真正的" pythonic",而是演示了该算法。

def IsPalindromeString(n):
    myLen = len(n)
    i = 0
    while i <= myLen/2:
        if n[i] != n[myLen-1-i]:
            return False
        i += 1
    return True

回答

Windows XP(可能也适用于2000)或者更高版本的BATCH脚本:

@echo off

call :is_palindrome %1
if %ERRORLEVEL% == 0 (
    echo %1 is a palindrome
) else (
    echo %1 is NOT a palindrome
)
exit /B 0

:is_palindrome
    set word=%~1
    set reverse=
    call :reverse_chars "%word%"
    set return=1
    if "$%word%" == "$%reverse%" (
        set return=0
    )
exit /B %return%

:reverse_chars
    set chars=%~1
    set reverse=%chars:~0,1%%reverse%
    set chars=%chars:~1%
    if "$%chars%" == "$" (
        exit /B 0
    ) else (
        call :reverse_chars "%chars%"
    )
exit /B 0

回答

C#:LINQ

var str = "a b a";
var test = Enumerable.SequenceEqual(str.ToCharArray(), 
           str.ToCharArray().Reverse());

回答

有很多方法可以做到。我猜关键是要以最有效的方式做到这一点(不循环字符串)。我会将其作为可以很容易地反转(使用C#)的char数组进行。

string mystring = "abracadabra";

char[] str = mystring.ToCharArray();
Array.Reverse(str);
string revstring = new string(str);

if (mystring.equals(revstring))
{
    Console.WriteLine("String is a Palindrome");
}

回答

到位算法。在传递给该函数之前,应进行任何预处理,例如不区分大小写或者去除空格和标点符号。

boolean IsPalindrome(string s) {
    for (int i = 0; i < s.Length / 2; i++)
    {
        if (s[i] != s[s.Length - 1 - i]) return false;
    }
    return true;
}

编辑:在循环条件中删除了不必要的" +1",并将保存的比较用于删除冗余的Length比较。感谢评论者!

回答

使用良好的数据结构通常会给教授留下深刻的印象:

将一半的字符推入堆栈(长度/ 2)。
弹出并比较每个字符,直到第一个不匹配为止。
如果堆栈具有零元素:回文。
*对于长度为奇数的字符串,请丢弃中间的字符。

回答

这是我的解决方案,无需使用strrev。用C#编写,但是它可以在任何具有字符串长度功能的语言中使用。

private static bool Pal(string s) {
    for (int i = 0; i < s.Length; i++) {
        if (s[i] != s[s.Length - 1 - i]) {
            return false;
        }
    }
    return true;
}

回答

此Java代码应在布尔方法内工作:

注意:我们只需要检查字符的前半部分和后半部分,否则我们将需要进行的检查数量重叠和加倍。

private static boolean doPal(String test) {
    for(int i = 0; i < test.length() / 2; i++) {
        if(test.charAt(i) != test.charAt(test.length() - 1 - i)) {
            return false;
        }
    }
    return true;
}

回答

Java解决方案:

public class QuickTest {

public static void main(String[] args) {
    check("AmanaplanacanalPanama".toLowerCase());
    check("Hello World".toLowerCase());
}

public static void check(String aString) {
    System.out.print(aString + ": ");
    char[] chars = aString.toCharArray();
    for (int i = 0, j = (chars.length - 1); i < (chars.length / 2); i++, j--) {
        if (chars[i] != chars[j]) {
            System.out.println("Not a palindrome!");
            return;
        }
    }
    System.out.println("Found a palindrome!");
}

}

回答

PHP示例:

$string = "A man, a plan, a canal, Panama";

function is_palindrome($string)
{
    $a = strtolower(preg_replace("/[^A-Za-z0-9]/","",$string));
    return $a==strrev($a);
}

删除所有非字母数字字符(空格,逗号,感叹号等)以允许上述完整句子以及简单单词。

回答

编辑:从评论:

bool palindrome(std::string const& s) 
{ 
  return std::equal(s.begin(), s.end(), s.rbegin()); 
}

C ++方式。

我朴素的实现使用优雅的迭代器。实际上,我们可能会检查
并在前向迭代器超过字符串的一半时停止。

#include <string>
#include <iostream>

using namespace std;
bool palindrome(string foo)
{
    string::iterator front;
    string::reverse_iterator back;
    bool is_palindrome = true;
    for(front = foo.begin(), back = foo.rbegin();
        is_palindrome && front!= foo.end() && back != foo.rend();
        ++front, ++back
        )
    {
        if(*front != *back)
            is_palindrome = false;
    }
    return is_palindrome;
}
int main()
{
    string a = "hi there", b = "laval";

    cout << "String a: \"" << a << "\" is " << ((palindrome(a))? "" : "not ") << "a palindrome." <<endl;
    cout << "String b: \"" << b << "\" is " << ((palindrome(b))? "" : "not ") << "a palindrome." <<endl;

}

回答

来自Delphi的另一个,我认为比提交的其他Delphi示例更严格。这很容易变成高尔夫比赛,但是我试图使我的可读性。

Edit0:我对性能特征很好奇,所以我做了一些测试。在我的机器上,我对60个字符串运行了此功能5000万次,这花了5秒钟。

function TForm1.IsPalindrome(txt: string): boolean;
var
  i, halfway, len : integer;
begin
  Result := True;
  len := Length(txt);

  {
  special cases:
  an empty string is *never* a palindrome
  a 1-character string is *always* a palindrome
  }
  case len of
    0 : Result := False;
    1 : Result := True;
    else begin
      halfway := Round((len/2) - (1/2));  //if odd, round down to get 1/2way pt

      //scan half of our string, make sure it is mirrored on the other half
      for i := 1 to halfway do begin
        if txt[i] <> txt[len-(i-1)] then begin
          Result := False;
          Break;
        end;  //if we found a non-mirrored character
      end;  //for 1st half of string
    end;  //else not a special case
  end;  //case
end;

在C#中,这是同一件事,除了我给它留了多个我不喜欢的出口点。

private bool IsPalindrome(string txt) {
  int len = txt.Length;

  /*
  Special cases:
  An empty string is *never* a palindrome
  A 1-character string is *always* a palindrome
  */    
  switch (len) {
    case 0: return false;
    case 1: return true;
  }  //switch
  int halfway = (len / 2);

  //scan half of our string, make sure it is mirrored on the other half
  for (int i = 0; i < halfway; ++i) {
    if (txt.Substring(i,1) != txt.Substring(len - i - 1,1)) {
      return false;
    }  //if
  }  //for
  return true;
}

回答

C#3一旦从头算起的字符与末尾的等价字符不匹配,它将立即返回false:

static bool IsPalindrome(this string input)
{
    char[] letters = input.ToUpper().ToCharArray();

    int i = 0;
    while( i < letters.Length / 2 )
        if( letters[i] != letters[letters.Length - ++i] )
            return false;

    return true;
}

回答

这是处理不同情况,标点符号和空格的Python版本。

import string

def is_palindrome(palindrome):
    letters = palindrome.translate(string.maketrans("",""),
                  string.whitespace + string.punctuation).lower()
    return letters == letters[::-1]

编辑:无耻地偷走了布莱尔·康拉德(Blair Conrad)的整洁答案,从我以前的版本中删除了稍微笨拙的列表处理。

回答

Smalltalk的三个版本,从最笨拙到正确。

在Smalltalk中,=是比较运算符:

isPalindrome: aString
    "Dumbest."
    ^ aString reverse = aString

消息#translateToLowercase返回的字符串为小写字母:

isPalindrome: aString
    "Case insensitive"
    |lowercase|
    lowercase := aString translateToLowercase.
    ^ lowercase reverse = lowercase

并且在Smalltalk中,字符串是Collection框架的一部分,我们可以使用消息#select:thenCollect:,所以这是最后一个版本:

isPalindrome: aString
    "Case insensitive and keeping only alphabetic chars
    (blanks & punctuation insensitive)."
    |lowercaseLetters|
    lowercaseLetters := aString
        select: [:char | char isAlphabetic]
        thenCollect: [:char | char asLowercase]. 
    ^ lowercaseLetters reverse = lowercaseLetters

回答

另一个C ++。针对速度和大小进行了优化。

`

bool is_palindrome(const std::string& candidate) {
    for(std::string::const_iterator left = candidate.begin(), right = candidate.end(); left < --right ; ++left)
        if (*left != *right)
            return false;
    return true;
}

`

回答

在Ruby中,转换为小写并剥离所有非字母的内容:

def isPalindrome( string )
    ( test = string.downcase.gsub( /[^a-z]/, '' ) ) == test.reverse
end

但这感觉就像在作弊,对吗?没有指针或者任何东西!因此,这也是C版本,但没有小写字母和字符剥离优点:

#include <stdio.h>
int isPalindrome( char * string )
{
    char * i = string;
    char * p = string;
    while ( *++i ); while ( i > p && *p++ == *--i );
    return i <= p && *i++ == *--p;
}
int main( int argc, char **argv )
{
    if ( argc != 2 )
    {
        fprintf( stderr, "Usage: %s <word>\n", argv[0] );
        return -1;
    }
    fprintf( stdout, "%s\n", isPalindrome( argv[1] ) ? "yes" : "no" );
    return 0;
}

好吧,我能得到这份工作很有趣; ^)

回答

我在这里看到很多错误的答案。任何正确的解决方案都需要忽略空格和标点符号(以及实际上的任何非字母字符),并且不区分大小写。

一些好的示例测试用例是:

"一个人,一个计划,一条运河,巴拿马。"

"丰田就是丰田。"

"一种"

"

以及一些非回文症。

C语言中的示例解决方案(注意:在此设计中,空字符串和空字符串被视为回文,如果不希望这样做,很容易更改):

public static bool IsPalindrome(string palindromeCandidate)
{
    if (string.IsNullOrEmpty(palindromeCandidate))
    {
        return true;
    }
    Regex nonAlphaChars = new Regex("[^a-z0-9]");
    string alphaOnlyCandidate = nonAlphaChars.Replace(palindromeCandidate.ToLower(), "");
    if (string.IsNullOrEmpty(alphaOnlyCandidate))
    {
        return true;
    }
    int leftIndex = 0;
    int rightIndex = alphaOnlyCandidate.Length - 1;
    while (rightIndex > leftIndex)
    {
        if (alphaOnlyCandidate[leftIndex] != alphaOnlyCandidate[rightIndex])
        {
            return false;
        }
        leftIndex++;
        rightIndex--;
    }
    return true;
}

回答

Hal的Ruby版本的更Ruby风格的重写:

class String
  def palindrome?
    (test = gsub(/[^A-Za-z]/, '').downcase) == test.reverse
  end
end

现在我们可以在任何字符串上调用" palindrome?"。

回答

C在房子里。 (不确定我们是否不想在这里使用C示例)

bool IsPalindrome(char *s)
{
    int  i,d;
    int  length = strlen(s);
    char cf, cb;

    for(i=0, d=length-1 ; i < length && d >= 0 ; i++ , d--)
    {
        while(cf= toupper(s[i]), (cf < 'A' || cf >'Z') && i < length-1)i++;
        while(cb= toupper(s[d]), (cb < 'A' || cb >'Z') && d > 0       )d--;
        if(cf != cb && cf >= 'A' && cf <= 'Z' && cb >= 'A' && cb <='Z')
            return false;
    }
    return true;
}

对于"赛车","赛车","赛车","赛车"和"赛车"来说,将返回true。修改为也包含符号或者空格会很容易,但是我认为仅计算字母(忽略大小写)会更有用。这适用于我在此处的答案中找到的所有回文,而且我无法将其欺骗为假阴性/阳性。

另外,如果我们不喜欢" C"程序中的bool,则显然可以返回int,对于true和false分别返回1和0。

回答

Perl:

sub is_palindrome($)
{
  $s = lc(shift); # ignore case
  $s =~ s/\W+//g; # consider only letters, digits, and '_'
  $s eq reverse $s;
}

它忽略大小写并去除非字母数字字符(其语言环境和unicodeneutral)。

回答

使用Java,使用Apache Commons String Utils:

public boolean isPalindrome(String phrase) {
  phrase = phrase.toLowerCase().replaceAll("[^a-z]", "");
  return StringUtils.reverse(phrase).equals(phrase);
}

回答

如果我们正在寻找数字和简单的单词,则给出了许多正确的答案。

但是,如果我们要寻找书面语言中的回文现象(例如"狗,恐慌,在宝塔中!"),则正确的答案是从句子的两端开始进行迭代非字母数字字符,如果发现任何不匹配,则返回false。

i = 0; j = length-1;

while( true ) {
  while( i < j && !is_alphanumeric( str[i] ) ) i++;
  while( i < j && !is_alphanumeric( str[j] ) ) j--;

  if( i >= j ) return true;

  if( tolower(string[i]) != tolower(string[j]) ) return false;
  i++; j--;
}

当然,去除无效字符,反转结果字符串并将其与原始字符串进行比较也可以。这取决于我们正在使用哪种语言。

回答

我必须这样做才能应对编程挑战,这是我的Haskell的摘要:

isPalindrome :: String -> Bool
isPalindrome n = (n == reverse n)

回答

Python:

if s == s[::-1]: return True

Java的:

if (s.Equals(s.Reverse())) { return true; }

PHP:

if (s == strrev(s)) return true;

Perl:

if (s == reverse(s)) { return true; }

Erlang:

string:equal(S, lists:reverse(S)).

回答

OCaml:

let rec palindrome s =
  s = (tailrev s)

来源

回答

Lisp:

(defun palindrome(x) (string= x (reverse x)))

回答

boolean IsPalindrome(string s) {
return s = s.Reverse();
}

回答

Perl:

sub is_palindrome {
    my $s = lc shift; # normalize case
    $s =~ s/\W//g;    # strip non-word characters
    return $s eq reverse $s;
}

回答

混淆的C版本:

int IsPalindrome (char *s)
{
  char*a,*b,c=0;
  for(a=b=s;a<=b;c=(c?c==1?c=(*a&~32)-65>25u?*++a,1:2:c==2?(*--b&~32)-65<26u?3:2:c==3?(*b-65&~32)-(*a-65&~32)?*(b=s=0,a),4:*++a,1:0:*++b?0:1));
  return s!=0;
}

回答

请注意,在上述C ++解决方案中,存在一些问题。

一种解决方案之所以效率低下,是因为它逐个传递了std :: string,并且它遍历了所有字符,而不是仅比较一半字符。然后,即使发现字符串不是回文,它也会继续循环,在报告" false"之前等待其结束。

另一个更好,它的函数很小,问题是除了std :: string之外,它无法测试其他任何东西。在C ++中,很容易将算法扩展到一大堆相似的对象。通过将其std :: string模板化为" T",它将对std :: string,std :: wstring,std :: vector和std :: deque都起作用。但是由于没有使用运算符<进行重大修改,因此std :: list不在其范围内。

我自己的解决方案试图证明C ++解决方案不会停止使用确切的当前类型,而是将努力工作任何行为均相同的方式,无论类型如何。例如,我可以将回文测试应用于std :: string,int向量或者" Anything"列表上,只要Anything可通过其操作符=(构建类型和类)进行比较。

请注意,模板甚至可以使用可用于比较数据的可选类型进行扩展。例如,如果我们想以不区分大小写的方式进行比较,或者甚至比较相似的字符(如,,?和e)。

就像列奥尼达斯国王会说的那样:"模板?这是C ++ !!!"

因此,在C ++中,至少有3种主要方法可以做到这一点,每种方法都可以导致另一种方法:

解决方案A:采用类似C的方式

问题在于,直到C ++ 0X,我们才能将char的std :: string数组视为连续的,因此我们必须"作弊"并检索c_str()属性。由于我们以只读方式使用它,因此应该可以...

bool isPalindromeA(const std::string & p_strText)
{
   if(p_strText.length() < 2) return true ;
   const char * pStart = p_strText.c_str() ;             
   const char * pEnd = pStart + p_strText.length() - 1 ; 

   for(; pStart < pEnd; ++pStart, --pEnd)
   {
      if(*pStart != *pEnd)
      {
         return false ;
      }
   }

   return true ;
}

解决方案B:更多的" C ++"版本

现在,我们将尝试应用相同的解决方案,但将其应用于任何通过操作符[]随机访问其项目的C ++容器。例如,任何std :: basic_string,std :: vector,std :: deque等。Operator []是对这些容器的恒定访问,因此我们不会损失不必要的速度。

template <typename T>
bool isPalindromeB(const T & p_aText)
{
   if(p_aText.empty()) return true ;
   typename T::size_type iStart = 0 ;
   typename T::size_type iEnd = p_aText.size() - 1 ;

   for(; iStart < iEnd; ++iStart, --iEnd)
   {
      if(p_aText[iStart] != p_aText[iEnd])
      {
         return false ;
      }
   }

   return true ;
}

解决方案C:模板powah!

它几乎可以与任何带有双向迭代器的无序STL类容器一起使用
例如,任何std :: basic_string,std :: vector,std :: deque,std :: list等。
因此,在以下情况下,可以将此功能应用于所有类似STL的容器:
1 T是带有双向迭代器的容器
2 T的迭代器指向可比较的类型(通过operator =)

template <typename T>
bool isPalindromeC(const T & p_aText)
{
   if(p_aText.empty()) return true ;
   typename T::const_iterator pStart = p_aText.begin() ;
   typename T::const_iterator pEnd = p_aText.end() ;
   --pEnd ;

   while(true)
   {
      if(*pStart != *pEnd)
      {
         return false ;
      }

      if((pStart == pEnd) || (++pStart == pEnd))
      {
         return true ;
      }

      --pEnd ;
   }
}

回答

C ++:

bool is_palindrome(const string &s)
{
    return equal( s.begin(), s.begin()+s.length()/2, s.rbegin());
}

回答

这里没有一个单一的解决方案考虑到回文也可以基于单词单位,而不仅仅是字符单位。

这意味着对于诸如"女孩,在比基尼上洗澡,盯着男孩,看到男孩在比基尼上盯着比基尼看着女孩"这样的回文症,给定的解决方案都没有返回正确的结果。

这是C#中的共同入侵版本。我确定它不需要正则表达式,但是它对于上述比基尼回文和"一个人,一个计划,一条运河到巴拿马!"同样有效。

static bool IsPalindrome(string text)
    {
        bool isPalindrome = IsCharacterPalindrome(text);
        if (!isPalindrome)
        {
            isPalindrome = IsPhrasePalindrome(text);
        }
        return isPalindrome;
    }

    static bool IsCharacterPalindrome(string text)
    {
        String clean = Regex.Replace(text.ToLower(), "[^A-z0-9]", String.Empty, RegexOptions.Compiled);
        bool isPalindrome = false;
        if (!String.IsNullOrEmpty(clean) && clean.Length > 1)
        {
            isPalindrome = true;
            for (int i = 0, count = clean.Length / 2 + 1; i < count; i++)
            {
                if (clean[i] != clean[clean.Length - 1 - i])
                {
                    isPalindrome = false; break;
                }
            }
        }
        return isPalindrome;
    }

    static bool IsPhrasePalindrome(string text)
    {
        bool isPalindrome = false;
        String clean = Regex.Replace(text.ToLower(), @"[^A-z0-9\s]", " ", RegexOptions.Compiled).Trim();
        String[] words = Regex.Split(clean, @"\s+");
        if (words.Length > 1)
        {
            isPalindrome = true;
            for (int i = 0, count = words.Length / 2 + 1; i < count; i++)
            {
                if (words[i] != words[words.Length - 1 - i])
                {
                    isPalindrome = false; break;
                }
            }
        }
        return isPalindrome;
    }

回答

我还没有看到任何递归,所以这里...

import re

r = re.compile("[^0-9a-zA-Z]")

def is_pal(s):

    def inner_pal(s):
        if len(s) == 0:
            return True
        elif s[0] == s[-1]:
            return inner_pal(s[1:-1])
        else:
            return False

    r = re.compile("[^0-9a-zA-Z]")
    return inner_pal(r.sub("", s).lower())

回答

这一切都很好,但是有没有办法在算法上做得更好?曾经有人在一次采访中要求我认识线性时间和恒定空间中的回文。

那时我什么也想不出来,但现在仍然无法。

(如果有帮助,我问面试官答案是什么。他说,我们可以构造一对哈希函数,以便仅当该字符串是回文时才将给定的字符串哈希为相同的值。我们实际上会做这对功能。)

回答

C ++

std::string a = "god";
std::string b = "lol";

std::cout << (std::string(a.rbegin(), a.rend()) == a) << " " 
          << (std::string(b.rbegin(), b.rend()) == b);

重击

function ispalin { [ "$( echo -n  | tac -rs . )" = "" ]; }
echo "$(ispalin god && echo yes || echo no), $(ispalin lol && echo yes || echo no)"

古努·阿克(Gnu Awk)

/* obvious solution */
function ispalin(cand, i) { 
    for(i=0; i<length(cand)/2; i++) 
        if(substr(cand, length(cand)-i, 1) != substr(cand, i+1, 1)) 
            return 0; 
    return 1; 
}

/* not so obvious solution. cough cough */
{ 
    orig = 
ispalin :: [Char] -> Bool
ispalin a = a == (let xi (y:my) = (xi my) ++ [y]; xi [] = [] in \x -> xi x) a
; while(
The treatment of diacritics varies. In languages such as Czech and Spanish, letters with diacritics or accents (except tildes) are not given a separate place in the alphabet, and thus preserve the palindrome whether or not the repeated letter has an ornamentation. However, in Swedish and other Nordic languages, A and A with a ring (?) are distinct letters and must be mirrored exactly to be considered a true palindrome.
) { stuff = stuff gensub(/^.*(.)$/, "\1", 1);
set l = index of left most character in word
set r = index of right most character in word

loop while(l < r)
begin
  if letter at l does not equal letter at r
    word is not palindrome
  else
     increase l and decrease r
end
word is palindrome
= gensub(/^(.*).$/, "\1", 1); } print (stuff == orig); }

哈斯克尔

在Haskell中一些脑筋急转弯的方式

template< typename Iterator >
bool is_palindrome( Iterator first, Iterator last, std::locale const& loc = std::locale("") )
{
    if ( first == last )
        return true;

    for( --last; first < last; ++first, --last )
    {
        while( ! std::isalnum( *first, loc ) && first < last )
            ++first;
        while( ! std::isalnum( *last, loc ) && first < last )
            --last;
        if ( std::tolower( *first, loc ) != std::tolower( *last, loc ) )
            return false;
    }
    return true;
}

普通英语

`"只需扭转字符串,如果与以前相同,那就是回文。"

回答

剔除不在A-Z或者a-z之间的任何字符的解决方案是非常以英语为中心的。带变音符号的字母,例如或者将被剥夺!

根据维基百科:

#!/usr/bin/perl

my @strings = ("A man, a plan, a canal, Panama.", "A Toyota's a Toyota.", 
               "A", "", "As well as some non-palindromes.");

for my $string (@strings) {
  print is_palindrome($string)  ? "'$string' is a palindrome (1)\n"
                                : "'$string' is not a palindrome (1)\n";
  print is_palindrome2($string) ? "'$string' is a palindrome (2)\n"
                                : "'$string' is not a palindrome (2)\n";
} 

sub is_palindrome {
  my $str = lc shift;
  $str =~ tr/a-z//cd;

  while ($str =~ s/^(.)(.*)(.)$//) {
    return unless  eq ;
  }

  return 1;
} 

sub is_palindrome2 {
  my $str = lc shift;
  $str =~ tr/a-z//cd;
  my @chars = split '', $str;

  while (@chars && shift @chars eq pop @chars) {};

  return scalar @chars <= 1;
}

因此,要涵盖许多其他语言,最好使用归类将变音符号转换为等效的非变音符号,或者适当地保留它们,然后仅在比较之前去除空格和标点符号。

回答

public bool IsPalindrome(string s)
            {
                if (String.IsNullOrEmpty(s))
                {
                    return false;
                }

                else
                {
                    char[] t = s.ToCharArray();
                    Array.Reverse(t);
                    string u = new string(t);
                    if (s.ToLower() == u.ToLower())
                    {
                        return true;
                    }
                }

                return false;
            }

回答

高效的C ++版本:

protected string StripNonAlphanumerics(string str)
{
    string strStripped = (String)str.Clone();
    if (str != null)
    {
        char[] rgc = strStripped.ToCharArray();
        int i = 0;
        foreach (char c in rgc)
        {
            if (char.IsLetterOrDigit(c))
            {
                i++;
            }
            else
            {
                strStripped = strStripped.Remove(i, 1);
            }
        }
    }
    return strStripped;
}
protected bool CheckForPalindrome()
{
    if (this.Text != null)
    {
        String strControlText = this.Text;
        String strTextToUpper = null;
        strTextToUpper = Text.ToUpper();
        strControlText =
                    this.StripNonAlphanumerics(strTextToUpper);
        char[] rgcReverse = strControlText.ToCharArray();
        Array.Reverse(rgcReverse);
        String strReverse = new string(rgcReverse);
        if (strControlText == strReverse)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

回答

这是另外两个Perl版本,两个都不使用reverse。两者都使用将字符串的第一个字符与最后一个字符进行比较,然后将其丢弃并重复测试的基本算法,但是它们使用不同的方法来获得各个字符(第一个字符使用正则表达式一次剥离一个,第二个将字符串拆分为字符数组)。

int IsPalindrome (const char *str)
{
    const unsigned len = strlen(str);
    const char *end = &str[len-1];
    while (str < end)
        if (*str++ != *end--)
            return 0;
    return 1;
}

回答

C#中的简易模式,仅使用基类库

编辑:刚刚看到有人做了Array.Reverse也

public boolean isPalindrome(String testString) {
    StringBuffer sb = new StringBuffer(testString);
    String reverseString = sb.reverse().toString();

    if(testString.equalsIgnoreCase(reverseString)) {
        return true;
    else {
        return false;
    }
}

回答

这是我在进行示例服务器控件时使用的C语言的另一个示例。可以在ASP.NET 3.5 Step by Step(MS Press)一书中找到。这是两种方法,一种剥离非字母数字,另一种检查回文。

/// <summary>
    /// Tests if a string is a palindrome
    /// </summary>
    public static bool IsPalindrome(this String str)
    {
        if (str.Length == 0) return false;
        int index = 0;
        while (index < str.Length / 2)
            if (str[index] != str[str.Length - ++index]) return false;

        return true;
    }

回答

const正确的C / C ++指针解决方案。循环中的最少操作。

class String
    def is_palindrome?
        letters_only = gsub(/\W/,'').downcase
        letters_only == letters_only.reverse
    end
end

puts 'abc'.is_palindrome? # => false
puts 'aba'.is_palindrome? # => true
puts "Madam, I'm Adam.".is_palindrome? # => true

回答

一个简单的Java解决方案:

def pal(s:String) = Symbol(s) equals Symbol(s.reverse)

回答

我的2c。避免每次都发生完整字符串反转的开销,并在确定字符串性质后立即利用短路返回。是的,我们应该先对字符串进行条件设置,但是IMO就是另一个函数的工作。

在C#中

Prolog

回答

红宝石:

palindrome(B, R) :-
palindrome(B, R, []).

palindrome([], R, R).
palindrome([X|B], [X|R], T) :-
palindrome(B, R, [X|T]).

回答

斯卡拉

public bool IsPalindrome(string s)
    {
        string formattedString = s.Replace(" ", string.Empty).ToLower();
        for (int i = 0; i < formattedString.Length / 2; i++)
        {
            if (formattedString[i] != formattedString[formattedString.Length - 1 - i])
                return false;
        }
        return true;
    }

回答

public bool IsPalindrome()
            if (MyString.Length == 0)
                return false;

            int len = MyString.Length - 1;

            int first = 0;
            int second = 0;

            for (int i = 0, j = len; i <= len / 2; i++, j--)
            {
                while (i<j && MyString[i] == ' ' || MyString[i] == ',')
                    i++;

                while(j>i && MyString[j] == ' ' || MyString[j] == ',')
                    j--;

                if ((i == len / 2) && (i == j))
                    return true;

                first = MyString[i] >= 97 && MyString[i] <= 122 ? MyString[i] - 32 : MyString[i];
                second = MyString[j] >= 97 && MyString[j] <= 122 ? MyString[j] - 32 : MyString[j];

                if (first != second)
                    return false;
            }

            return true;
  }
##代码##

回答

##代码##

这种方法适用于像"我看见老鼠了吗"这样的刺痛。但是我觉得我们需要通过正则表达式消除特殊字符。

回答

C版本:

假定MyString为char [],在验证字符串后返回方法,它忽略空格和<,>,但这可以扩展为忽略更多,可能实现忽略列表的正则表达式匹配。

##代码##

快速测试案例

消极的

  1. ABCDA
  2. AB CBAG
  3. A#$ BDA
    4.空/空

积极的

  1. ABCBA
    2.一个人计划一条运河,巴拿马
  2. ABC BA
  3. M
  4. ACCB

让我知道任何想法/错误。