简体   繁体   English

回文检查的递归方法

[英]Recursive method for palindrome checkup

Is it even possible to define a recursive method for palindrome checkup with the following argument list?甚至可以使用以下参数列表为回文检查定义递归方法吗?

int testPalindromeRecursive(char* str, int len) { ... }

Note: no external sub-functions or global variables have to be used注意:不必使用外部子函数或全局变量

I think this is impossible, because you have to remember the last (front) index position somehow.我认为这是不可能的,因为您必须以某种方式记住最后一个(前)索引位置。

Yes, it is completely possible - as several people have mentioned.是的,这是完全可能的 - 正如几个人提到的。

Base Cases:基本案例:

  • If len <= 1, return True如果 len <= 1,则返回 True
  • If str[0] != str[len-1] return False如果 str[0] != str[len-1] 返回 False

Else: recurse with (str+1, len -2)否则:递归 (str+1, len -2)

1) A string with no characters or just a single character is a palindrome 1) 没有字符或只有一个字符的字符串是回文

2) if the first and last characters of a string with 2 or more characters are equal, and the substring excluding the terminal characters is a palindrome, the whole string is a palindrone. 2)如果2个以上字符的字符串首尾字符相等,且不包括终结字符的子串为回文,则整个字符串为回文。

As for me then I would declare the function like至于我,那么我会像这样声明函数

int testPalindromeRecursive( const char *s, size_t n );

In this case the function would contain only one return statement在这种情况下,该函数将只包含一个 return 语句

int testPalindromeRecursive( const char *s, size_t n ) 
{
    return ( n < 2 ) || 
           ( s[0] == s[n-1] && testPalindromeRecursive( s + 1, n - 2 ) );   
}

Nevertheless the function can be wriiten the following way as it is shown in the demonstrative program below尽管如此,该函数可以按以下方式编写,如下面的演示程序所示

#include <stdio.h>

int testPalindromeRecursive( char *str, int len ) 
{
    if ( len < 0 ) return 0;

    return ( len < 2 ) || 
           ( str[0] == str[len-1] && testPalindromeRecursive( str + 1, len - 2 ) );   
}

int main( void ) 
{
    char s[] = "abbcccbba"; 

    printf( "testPalindromeRecursive( \"%s\" ) is %s\n",
            s, testPalindromeRecursive( s, sizeof( s ) - 1 ) ? "true" : "false" );

    return 0;
}

The program output is程序输出是

testPalindromeRecursive( "abbcccbba" ) is true

Take into account that you may adhere to the common convention according to which string functions do not check whether the passed character pointer is equal to NULL.考虑到您可能遵守通用约定,根据该约定,字符串函数不检查传递的字符指针是否等于 NULL。 It is the responsibility of the programmer to check this before the function call.在函数调用之前检查这一点是程序员的责任。

I'm tempted to offer Python version here:我很想在这里提供 Python 版本:

 def ispalindrome(word):
     if len(word) < 2: return True
     if word[0] != word[-1]: return False
     return ispalindrome(word[1:-1])

>>> ispalindrome('racecar')
True
>>> ispalindrome('racekcar')
False
>>> ispalindrome('a')
True
>>> ispalindrome('aba')
True

My solution is capable of skipping whitespace:我的解决方案能够跳过空格:

int test_palindrom_recursive(char* str, int len)
{
    if (len < 1) return 0;
    int frontIndexToPass = 0, endIndexToPass = 0;
    if (str[0] == ' ')
    {
        for (int front = 0; front < len - 1; front++)
        {
            if (str[front] == ' ') frontIndexToPass++;
            else break;
        }
    }

    if (str[len - 1] == ' ')
    {
        for (int end = len - 1; end >= 0; end--)
        {
            if (str[end] == ' ') endIndexToPass++;
            else break;
        }
    }

    if (tolower(str[0 + frontIndexToPass]) == tolower(str[len - endIndexToPass - 1]))
    {
        if (len <= 2) return 1;
        else
            test_palindrom_rekursiv(str + frontIndexToPass + 1,
                len - endIndexToPass - frontIndexToPass - 2);
    }
    else return 0;
}

Using C# I managed to get this:使用C#我设法得到这个:

int testPalindromeRecursive(string str, int len)
{
    if (len <= 1)
        return 0;

    if (str[0] == str[len - 1])
    {
        str = str.Substring(1, len - 2);
        return testPalindromeRecursive(str, str.Length);
    }
    return -1;
}

ref is doing almost the same job as * here. ref在这里所做的工作与*几乎相同。 => Removed ref because it was not the best option since it didn't allow the use of const =>删除了ref因为它不是最好的选择,因为它不允许使用const

This works just fine for me:这对我来说很好用:

#include <stdio.h>
#include <string.h>

int testPalindromeRecursive(char* str, int len)
{
    if (len <= 1)
        return 1;

    if (str[0] != str[len-1])
        return 0;

    return testPalindromeRecursive(str+1, len-2);
}

int main()
{
    int i;
    char *strs[5] = { "test", "tvt", "a", "palindrome", "racecar" };

    for (i = 0; i < 5; i++)
        printf("%s = %d\n", strs[i], testPalindromeRecursive(strs[i], strlen(strs[i])));
}

Edit: Fix according to comments to check for length==0 as well编辑:根据评论修复以检查长度==0

[EDIT2] [编辑2]
This is the correct answer in C. Although it has been downvoted three times, I'm keeping it as it's the ONLY correct answer in C on this page.这是 C 语言中的正确答案。虽然它已经被否决了 3 次,但我仍然保留它,因为它是此页面上 C 语言中的唯一正确答案。

[EDIT] [编辑]
fixed my answer.修复了我的答案。

In C:在 C 中:

#include <stdio.h>
#include <string.h>

int testPalindromeRecursive(char* str, int len)
{
    if (len <= 1)
        return 0;
    if (str[0] != str[len-1])
        return 1;
    return testPalindromeRecursive(str+1, len-2);
}

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf("Usage: %s <string>\n", argv[0]);
        return 1;
    }
    if (!testPalindromeRecursive(argv[1], strlen(argv[1])))
        printf("Palindrom\n");
    else
        printf("Not palindrom\n");
    return 0;
}

Running example for the case mentioned in a comment by kdopen (base case failure when testPalindromeRecursive("a", 1): kdopen 评论中提到的案例的运行示例(testPalindromeRecursive("a", 1) 时基本案例失败:

./palind a  
Palindrom

More running examples mentioned by kdopen: kdopen 提到的更多运行示例:

./mine \\"a <-- the \\ is to escape the " Not palindrom ./mine \\"a <-- \\ 是为了逃避" Not palindrom

./mine \\"\\" Palindrom ./mine \\"\\" 回文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM