Reputation: 40481
I've got an assignment where I need to check if a given string is a palindrome or not recursively.
E.G. :
aD1Da // returns 1
asd1s // returns 0
The function signature needs to look like this:
int isPolindrom(char str[]);
Which means I'm getting only one parameter. I managed to build a solution using a static variable (The function will be called more than once, so we were instructed not to use static variables, though my solution works for more than 1 call).
My solution:
static flag = 0;
int isPolindrom(char str[])
{
static int pos = 1;
if (flag == 1) {
pos = 1; // Reset
flag = 0; // Reset
}
if (pos >= strlen(str)) {
flag = 1;
return 1;
}
if (*str == *(str + strlen(str) - pos)) {
pos++;
return isPolindrom(str + 1);
}
else return 0;
}
It's also possible using a secondary function, but I was wondering if and how is it possible to do this without static variables and without writing secondary functions.
In the automatic tests they are sending me the string as a constant string. For example:
isPolindrom("abcba")
Upvotes: 1
Views: 623
Reputation: 30926
Yes it is possible. Assuming that string is null terminated and is mutable we will do this
int isPolindrom(char s[])
{
int l = 0;
while(s[l]) l++;
if(l == 2)
return s[0]==s[1];
if(l <= 1)
return 1;
char c=s[l-1];
s[l-1]=0;
int result = (s[0]==c) && isPolindrom(s+1);
s[l-2]=c;
return result ;
}
Though it doesn't change the passed argument - we are modifying it internally. That's why modifiable sting requirement was needed.
Note my earlier answer was considering that you couldn't use any function but as OP made it clear we can easily use standard library functions like malloc
etc. That's why this solution using dynamically allocated memory.
With the given constraint
int isPolindrom(const char *s)
{
int l = 0;
while(s[l]) l++;
if(l == 2)
return s[0]==s[1];
if(l == 1)
return 1;
char *ss = malloc(l-1);
if( ss == NULL ){
perror("Error in malloc");
exit(EXIT_FAILURE);
}
for(int i=0;i<l-2;i++)
ss[i]=s[i+1];
ss[l-2]=0;
int p = (s[0]==s[l-1]) && isPolindrom(ss);
free(ss);
return p;
}
Upvotes: 3
Reputation: 12837
This is my take on this:
first == last
, if yes - recursive call with the inner string#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
bool is_palindrome(char * str){
// end conditions
if (!str)
return false;
if (strlen(str) < 2)
return true;
// check first vs. last
if (str[0] == str[strlen(str) - 1]){
// remove first & last chars (copy to array to allow this)
char tmp_arr[strlen(str) - 1];
strncpy(tmp_arr, str+1, strlen(str) - 2);
tmp_arr[strlen(str) - 2] = '\0';
return is_palindrome(tmp_arr);
/* if string was mutable - this would be easier:
str[strlen(str) - 1] = '\0';
return is_palindrome(str + 1);
*/
}
return false;
}
int main(){
printf(is_palindrome("abcddcba") ? "true\n" : "false\n");
printf(is_palindrome("abcddcbaa") ? "true\n" : "false\n");
printf(is_palindrome("abcd dcba") ? "true\n" : "false\n");
while(1);
return 0;
}
Upvotes: 1
Reputation: 7542
Creating a new string inside palindrome()
.
int palindrome(char *str)
{
int len= strlen(str);
if(len<=1)
return true;
char a=str[0];
char b=str[len-1];
char *newstr=malloc(len-2+1);
for(int i=1;i<len-1;i++)
newstr[i-1] = str[i];
newstr[len-2]='\0';
int res = (a==b && palindrome(newstr));
free(newstr);
return res;
}
and call it as
palin("abcba");
Upvotes: 1