3

For some reason my palindrome function is not working, I'd love some help on it:

Code

int Pal(char *s, int a, int b)
{
    if (a>= b)
        return 1;

    if (s[a] != s[b])
        return 0;

    return Pal(s, ++a , --b);
} 

int main()
{
    char *s = "civic";

    if (Pal(s , 1, strlen(s)))
        printf("YES\n");
    else
        printf("No\n");
}

It keeps printing No, and I'm clueless to why this is happening.

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
Faisal
  • 159
  • 9
  • 1
    Finding a palindrome is not a problem that requires recursivity. There's no hierarchy involved, nor is there a stack collection. – Jazzwave06 Feb 24 '19 at 15:26
  • 3
    Don't forget that array indexes are *zero* based. That means an array of 5 elements have indexes from `0` to `4` (inclusive). – Some programmer dude Feb 24 '19 at 15:26
  • The first element of `char *s = "civic";` is `s[0]`, the last one (not counting the `'\0'`) is `s[4]`. – pmg Feb 24 '19 at 15:26
  • Try `Pal(s , 0 ,strlen(s)-1 )` – Hanjoung Lee Feb 24 '19 at 15:27
  • problem solved, Thank you all! – Faisal Feb 24 '19 at 15:29
  • `s` should be `char const *` both in `main()` and and as the parameter of `Pal()`. `int main()` should be `int main(void)` if this is supposed to be `C` and not `C++`. – Swordfish Feb 24 '19 at 15:31
  • in the recursive call, you can just write `return Pal(s, a+1, b-1);`, you don't need to change `a` and `b` itself – Aemyl Feb 24 '19 at 15:40
  • 1
    @sturcotte06 Very few problems *requires* recursion, but very many are *suitable* to be solved with recursion. I don't see any problem using recursion for this. – klutt Feb 24 '19 at 15:54
  • 1
    @Broman `unsigned int sum(unsigned int a, unsigned int b) { if (b == 0) return a; return sum(++a, --b); }` ;) – Jazzwave06 Feb 24 '19 at 16:19
  • @Calvin If one of the questions solved your problem, you should [accept it](https://stackoverflow.com/help/accepted-answer). – dbush Feb 24 '19 at 16:35

3 Answers3

6

You're starting point for the function is incorrect:

if (Pal(s , 1 ,strlen(s) ))

Arrays in C and C++ have a starting index of 0. So you're actually starting at the second character and ending at the null terminating byte at the end of the string.

Use a value of 1 less for both the start and the end:

if (Pal(s, 0, strlen(s)-1 ))
dbush
  • 205,898
  • 23
  • 218
  • 273
1

Use the following code:

bool isPalindrome(char *str, int startIndex, int endIndex)
{
  if ( startIndex >= endIndex)
    return true;

  if (str[startIndex] != str[endIndex])
    return false;

  return isPalindrome(str, ++startIndex , --endIndex);
} 
int main()
{
  char *str = "civic";

  if (isPalindrome(str , 0, strlen(str)-1))
    printf("YES\n");
  else
    printf("No\n");
}

Some points to consider

  1. character arrays are used for string in C.
  2. Arrays in C have a starting index of 0
  3. Arrays in C endIndex is size - 1.

Other Improvements possible, though they are very minor:

  1. Have returnType of recursive function as boolean (lesser memory).
  2. Have more clearer names for data members.

Example:

char string[]={'c,'i','v','i','c'};  //size=5
// indexes:     0  1   2   3   4
Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33
0

The character at position strlen(s) is not the last character in the string, but the \0 character that marks its end. If you want to check against the last one, change

    if (Pal(s , 1, strlen(s)))

by

    if (Pal(s , 0, strlen(s)-1))

(but be careful to check first that the string s has at least one character, or the expression will be wrong ---you cannot check for palindrome an empty string---)

String indices go from 0 to one character less than strlen(s).

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31