Проверка строки, если это палиндром или не использует указатель - PullRequest
1 голос
/ 06 марта 2020

Что означает жирный шрифт в этом коде? Мне удалось выполнить большую часть шаблона (предоставленного моим учителем в качестве задания), я не могу найти причину этой жирной части.

Я мог бы использовать strlen-часть до ее появления, я знаю, что можно все равно напиши код вообще без strlen.

#include <stdio.h>

int strlen(char *str)
{
    int c = 0;
    while (str[c] != '\0')
    {
        c++;
    }
    return c;
}

int isPalindrome(char *str)
{
    char *ptr1 = str;
    char *ptr2 = str + strlen(str) - 1;
    while (ptr2 > ptr1)
    {
        if (tolower(*ptr1) != tolower(*ptr2))
        {
            return (0);
        }
        ptr1++;

        ptr2--;
    }
    return (1);
}
/**
            This function will
                -return 1 if the given string is Palindrome,
                -return 0 if the given string is not Palindrome.
        */

**int n = strlen(str);
// Write your code here**
}

int main()
{
    char *str = "ABCCBA ABCCBA"; //your input
    if (isPalindrome(str))
    {
        printf("%s is a palindrome", str);
    }
    else
    {
        printf("%s is not a palindrome", str);
    }
}

Ответы [ 3 ]

1 голос
/ 06 марта 2020

Учитель намекнул, что необходимо использовать длину входной строки с нулевым символом в конце. Они сохранили это полезное значение внутри переменной.

Если вам необходимо использовать код, предоставленный учителем, то переместите весь ваш код ПОСЛЕ этой строки, и в вашем коде замените strlen(str) на n.

int isPalindrome(char *str)
{
        /**
            This function will
                -return 1 if the given string is Palindrome,
                -return 0 if the given string is not Palindrome.
        */

    int n = strlen(str);
    // Write your code here

    char *ptr1 = str;
    char *ptr2 = str + n - 1;
    while (ptr2 > ptr1)
    {
        if (tolower(*ptr1) != tolower(*ptr2))
        {
            return (0);
        }
        ptr1++;

        ptr2--;
    }
    return (1);
}
0 голосов
/ 06 марта 2020

Вы можете реализовать isPalindrome без каких-либо знаний об указателях. Я предпочитаю использовать индексы вместо указателей, посмотрите на следующий пример

#include <stdio.h>
#include <assert.h>

int strLen(const char *str)
{
    int n = 0;
    while(str[n]) { ++n; }
    return n;
}

int isPalindrome(const char *str) {
    int i = 0;
    int j = strLen(str) - 1;
    while (i < j) {
        if (str[i++] != str[j--]) { return 0; }
    }
    return 1;    
}

int main() {
    assert(isPalindrome(""));
    assert(isPalindrome("a"));
    assert(isPalindrome("aa"));
    assert(isPalindrome("aba"));
    assert(!isPalindrome("ab"));
    assert(!isPalindrome("aab"));
}
0 голосов
/ 06 марта 2020

Я думаю, что шаблон функции начинается с объявления переменной n, которая получает размер переданной строки.

int isPalindrome(char *str)
{
    /**
        This function will
            -return 1 if the given string is Palindrome,
            -return 0 if the given string is not Palindrome.
    */
    int n = strlen(str);
    // Write your code here*
}

Но вы проигнорировали это объявление и использовали выражение strlen( str ) в это объявление

char *ptr2 = str + strlen(str) - 1;

вместо записи, например,

int n = strlen(str);
//...
char *ptr2 = str + n - 1;

В любом случае назначение выглядит не очень хорошо. Например, это объявление

char *ptr2 = str + strlen(str) - 1;

может вызывать неопределенное поведение, когда переданная строка пуста.

Параметры функций должны быть объявлены с квалификатором const, поскольку переданные строки в качестве аргументов не являются изменено в функциях.

Аргумент стандартной функции tolower должен быть преобразован в тип unsigned char.

Функции могут выглядеть следующим образом

size_t strlen( const char *str )
{
    size_t n = 0;

    while ( str[n] ) ++n;

    return n;
}

int isPalindrome( const char *str )
{
    const char *ptr1 = str;
    const char *ptr2 = str + strlen( str );

    if ( ptr1 != ptr2 )
    {
        while ( ptr1 < --ptr2 && 
                tolower( ( unsigned char )*ptr1 ) == tolower( ( unsigned char )*ptr2 ) ) 
        {
            ++ptr1;
        }           
    }

    return !( ptr1 < ptr2 );
}

Также, если функция strlen также должна использовать указатели, она может выглядеть следующим образом

size_t strlen( const char *str )
{
    const char *p = str;

    while ( *p ) ++p;

    return p - str;
}

Вот демонстрация того, как должны выглядеть ваши функции.

#include <stdio.h>
#include <ctype.h>

size_t strlen( const char *str )
{
    const char *p = str;

    while ( *p ) ++p;

    return p - str;
}

int isPalindrome( const char *str )
{
    const char *ptr1 = str;
    const char *ptr2 = str + strlen( str );

    if ( ptr1 != ptr2 )
    {
        while ( ptr1 < --ptr2 && 
                tolower( ( unsigned char )*ptr1 ) == tolower( ( unsigned char )*ptr2 ) ) 
        {
            ++ptr1;
        }           
    }

    return !( ptr1 < ptr2 );
}


int main(void) 
{
    char *str = "ABCCBA ABCCBA"; //your input

    if ( isPalindrome( str ) )
    {
        printf("\"%s\" is a palindrome\n", str);
    }
    else
    {
        printf("\"%s\" is not a palindrome\n", str);
    }   

    return 0;
}

Вывод программы

"ABCCBA ABCCBA" is a palindrome
...