int is_palendrome(char *arr,int n,int l,int r)
Spelling: palindrome
Consider including <stdbool.h>
and returning a bool
value.
The arguments could do with more descriptive names. It's particularly unclear what n
is for, as it appears to be unused within the function.
Why does arr
point to modifiable char
? I think we should pass const char*
.
l
and r
might be better as size_t
values (include <stdint.h>
) since they are used to index a string. Alternatively, we could just pass a pair of pointers:
#include <stdbool.h>
bool is_palindrome(const char *left, const char *right)
{
while (left < right) {
if (*left++ != *right--)
return false;
}
return true;
}
int bps(char *arr,int n,int r, int l)
This one could do with a better name. And we should document what it returns. In fact, at present, it's missing a return
statement, so that needs fixing.
if(l==n)
return 0;
int x=0;
That indentation style is unhelpful. It's possibly caused by pasting tab characters into Stack Exchange (which has tab-stops every 4 characters, unlike most terminals). That's a good reason to use spaces for indentation (or, like Linux sources, use a full tab for each indent level).
The variable x
which remembers which branch of the if
we took doesn't add value - just move the if (x==1)
code into those branches:
if(is_palendrome(arr,n,l,r))
{
/* x=1; */
…
l = r+1;
r = n;
} else {
--r;
}
bps(arr,n,r,l);
for(int i=l;i<=r;i++)
{
printf("%c",arr[i]);
}
printf("\n");
Performing our output within the function limits its usefulness. We're not able to do anything else with the results in a future program.
Also, we don't need to write a loop to print a substring - we can do that with %s
conversion by passing a precision specification like this:
printf("%.*s\n", r+1-l, arr+l);
The signature of the main function should be int main(void)
- Standard C does not permit main()
with a void
return type. However, the magic of main()
is that you don't need to write a return
statement - if omitted, then main()
(and only main()
) will return a success value (zero).
The variable array
seems unused.
Changing the interface
To use the results more flexibly, I would write the function to return the length of the longest initial palindrome. That way, the caller can choose what to do with it, and whether to continue looking at the rest of the string.
#include <stdbool.h>
bool is_palindrome(const char *left, const char *right)
{
while (left < right) {
if (*left++ != *right--)
return false;
}
return true;
}
/* Returns the length of the longest palindrome anchored to the
beginning of the string. This will be zero if the string is
empty.
*/
size_t longest_initial_palindrome(const char* s)
{
size_t len = strlen(s);
while (len && !is_palindrome(s, s + len - 1)) {
--len;
}
return len;
}
For example, here's a program that processes each of its arguments, and enumerates the palindromes therein:
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
const char *s = argv[i];
printf("\n%s:\n", s);
size_t index = 0;
size_t pal_len;
while ((pal_len = longest_initial_palindrome(s))) {
printf("%zu: %.*s\n", ++index, (int)pal_len, s);
s += pal_len;
}
}
}
Algorithm
The program doesn't work as advertised. For example, input abaccccab
should find longest palindromic substring baccccab
, and so split a
/baccccab
. Instead, it starts from the left, and splits as aba
/cccc
/a
/b
.
Fixing that problem is left as an exercise.