S
Sathyaish
I had recieved an email sometime ago wherein I was asked to write a
function that parsed a given string for the longest pallindrome it
contained and replaced the pallindrome with another string, given as
its second argument. In finding a pallindrome, however, all the
characters were to be considered equal. Therefore, a space, a comma,
or any punctuation for that matter was to be treated like any other
character.
In solving that question, here's what I came up with after a try or
two:
//File R.h
#ifndef __R__
#define __R__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LEN 1000
int ReplacePallindromes(char**, char*);
int Replace(char**, const int, const int, const
char*);
char* SubString(char*, const int, const int);
void Reverse(char*);
enum MatchTypes
{
None=0,
OddLength=1,
EvenLength=2
};
#endif
//File Globals.h
#include "R.h"
int ReplacePallindromes(char **InStr, char
*ReplaceWith)
{
int Len, LenReplaceWith, MatchFound, LastReplacement;
int Counter;
int ReverseCounter;
int SomeCounter;
int SomeOtherCounter;
char* SubStr1;
char* SubStr2;
LastReplacement=-100;
SubStr1=SubStr2=NULL;
MatchFound=0;
if (*InStr==NULL || ReplaceWith==NULL) return -1;
if (*ReplaceWith==0) return -1;
LenReplaceWith=strlen(ReplaceWith);
Len=strlen(*InStr);
if (Len<2) return -1;
Counter=ReverseCounter=SomeCounter=SomeOtherCounter=0;
for(Counter=0; Counter<Len; Counter++)
{
NextCharFromFront:
for(ReverseCounter=Len-1; ReverseCounter>Counter;
ReverseCounter--)
{
if (*((*InStr)+Counter) == *((*InStr)+ReverseCounter))
{
MatchFound=1;
for(SomeCounter=1, SomeOtherCounter=ReverseCounter-1;
Counter+SomeCounter<=SomeOtherCounter; SomeCounter++,
SomeOtherCounter--)
{
SubStr1=SubString(*InStr, Counter,
Counter+SomeCounter);
SubStr2=SubString(*InStr, SomeOtherCounter,
ReverseCounter);
Reverse(SubStr2);
MatchFound=((strcmp(SubStr1, SubStr2)==0)? 1:0);
if (MatchFound==0)
{
free(SubStr1);
free(SubStr2);
break;
}
free(SubStr1);
free(SubStr2);
}//End of SomeCounter for loop
if(MatchFound==1 && Counter+SomeCounter>=SomeOtherCounter)
{
//This is the largest pallindrome, replace it
LastReplacement=Replace(InStr, Counter,
ReverseCounter, ReplaceWith);
Len=strlen(*InStr);
Counter=LastReplacement+1;
goto NextCharFromFront;
}
}//End of if InStr[Counter] == InStr[ReverseCounter]
}//End of ReverseCounter for loop
}// End of Counter for loop
return 0;
} //end of function
int Replace(char **InStr, const int From,
const int To, const char *ReplaceWith)
{
char* NewString;
int LenReplaceWith, Counter, k, Len;
if(*InStr==NULL || ReplaceWith==NULL) return -1;
Len=strlen(*InStr);
LenReplaceWith=strlen(ReplaceWith);
NewString=NULL;
NewString=(char*)malloc(sizeof(char)*(Len-(To-From+1)+LenReplaceWith+1));
for(Counter=0;
Counter<(Len-(To-From+1)+LenReplaceWith+1); Counter++)
*(NewString+Counter)=0;
for(Counter=0;Counter<=From-1;Counter++)
*(NewString+Counter)=*((*InStr)+Counter);
for(Counter=0;Counter<LenReplaceWith; Counter++)
*(NewString+From+Counter)=*(ReplaceWith+Counter);
for(Counter=To+1, k=0; Counter<Len; Counter++, k++)
*(NewString+From+LenReplaceWith+k)=*((*InStr)+Counter);
*(NewString+From+LenReplaceWith+k)=0;
free(*InStr);
Len=strlen(NewString);
*InStr=(char*)malloc(sizeof(char)*(Len+1));
if((*InStr)==NULL) return -1;
strcpy(*InStr, NewString);
free(NewString);
return (From-1+LenReplaceWith);
}
char* SubString(char* Source, const int From, const
To)
{
int Len, Counter;
char *NewString;
Len=strlen(Source);
if(Source==NULL) return NULL;
if (From<0) return NULL;
if (From>To) return NULL;
if ((From>Len) || (To>Len)) return NULL;
NewString=(char*)malloc(sizeof(char)*(To-From+2));
for(Counter=From; Counter<=To; Counter++)
{
*(NewString+Counter-From)=*(Source+Counter);
}
NewString[Counter-From]=0;
return NewString;
}
void Reverse(char* Str)
{
int i, j, len;
char temp;
i=j=len=temp=0;
if(Str!=NULL)
{
len=strlen(Str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=Str;
Str=Str[j];
Str[j]=temp;
}
}
}
//File R.C
#include "R.h"
int main(void)
{
char c, *InStr, *ReplaceWith;
int i;
c=' ';
i=0;
InStr=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(InStr==NULL) return -1;
ReplaceWith=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(ReplaceWith==NULL) return -1;
printf("\nEnter a string (1000 characters maximum):");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN)) InStr[i++]=c;
InStr=0;
c=' ';
i=0;
printf("\n\nEnter the string that you wish to replace\npallindromes
with (1000 characters maximum): ");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN))
ReplaceWith[i++]=c;
ReplaceWith=0;
if(ReplacePallindromes(&InStr, ReplaceWith)==0)
{
printf("\nThe modified string is:\n\n %s\n", InStr);
}
else
{
printf("An error occured. The program will now end.");
free(InStr);
free(ReplaceWith);
return -1;
}
free(InStr);
free(ReplaceWith);
return 0;
}
I was asked as to why I'd taken a pointer to a pointer as the first
argument of the ReplacePallindrome function. I thought I'd write a
tutorial to explain this thing that I'd arrived at by heuristic
endeavours in the past, when I practiced pointers. So here's a
tutorial I've written. Even at the risk of being laughed at, I present
it to all of you learned people out here, so you may review it,
because, with a few refinements, I intend to get it published if it is
all ok. I am only learning C and thus have written only what I've
coded and tested with my own hands. Please give me your comments as to
how good or bad it is.
http://sathyaishc.tripod.com/Tutorial.doc
(You have to do a right-click and say "Save As" or "Save Target As")
Thanks!
function that parsed a given string for the longest pallindrome it
contained and replaced the pallindrome with another string, given as
its second argument. In finding a pallindrome, however, all the
characters were to be considered equal. Therefore, a space, a comma,
or any punctuation for that matter was to be treated like any other
character.
In solving that question, here's what I came up with after a try or
two:
//File R.h
#ifndef __R__
#define __R__
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LEN 1000
int ReplacePallindromes(char**, char*);
int Replace(char**, const int, const int, const
char*);
char* SubString(char*, const int, const int);
void Reverse(char*);
enum MatchTypes
{
None=0,
OddLength=1,
EvenLength=2
};
#endif
//File Globals.h
#include "R.h"
int ReplacePallindromes(char **InStr, char
*ReplaceWith)
{
int Len, LenReplaceWith, MatchFound, LastReplacement;
int Counter;
int ReverseCounter;
int SomeCounter;
int SomeOtherCounter;
char* SubStr1;
char* SubStr2;
LastReplacement=-100;
SubStr1=SubStr2=NULL;
MatchFound=0;
if (*InStr==NULL || ReplaceWith==NULL) return -1;
if (*ReplaceWith==0) return -1;
LenReplaceWith=strlen(ReplaceWith);
Len=strlen(*InStr);
if (Len<2) return -1;
Counter=ReverseCounter=SomeCounter=SomeOtherCounter=0;
for(Counter=0; Counter<Len; Counter++)
{
NextCharFromFront:
for(ReverseCounter=Len-1; ReverseCounter>Counter;
ReverseCounter--)
{
if (*((*InStr)+Counter) == *((*InStr)+ReverseCounter))
{
MatchFound=1;
for(SomeCounter=1, SomeOtherCounter=ReverseCounter-1;
Counter+SomeCounter<=SomeOtherCounter; SomeCounter++,
SomeOtherCounter--)
{
SubStr1=SubString(*InStr, Counter,
Counter+SomeCounter);
SubStr2=SubString(*InStr, SomeOtherCounter,
ReverseCounter);
Reverse(SubStr2);
MatchFound=((strcmp(SubStr1, SubStr2)==0)? 1:0);
if (MatchFound==0)
{
free(SubStr1);
free(SubStr2);
break;
}
free(SubStr1);
free(SubStr2);
}//End of SomeCounter for loop
if(MatchFound==1 && Counter+SomeCounter>=SomeOtherCounter)
{
//This is the largest pallindrome, replace it
LastReplacement=Replace(InStr, Counter,
ReverseCounter, ReplaceWith);
Len=strlen(*InStr);
Counter=LastReplacement+1;
goto NextCharFromFront;
}
}//End of if InStr[Counter] == InStr[ReverseCounter]
}//End of ReverseCounter for loop
}// End of Counter for loop
return 0;
} //end of function
int Replace(char **InStr, const int From,
const int To, const char *ReplaceWith)
{
char* NewString;
int LenReplaceWith, Counter, k, Len;
if(*InStr==NULL || ReplaceWith==NULL) return -1;
Len=strlen(*InStr);
LenReplaceWith=strlen(ReplaceWith);
NewString=NULL;
NewString=(char*)malloc(sizeof(char)*(Len-(To-From+1)+LenReplaceWith+1));
for(Counter=0;
Counter<(Len-(To-From+1)+LenReplaceWith+1); Counter++)
*(NewString+Counter)=0;
for(Counter=0;Counter<=From-1;Counter++)
*(NewString+Counter)=*((*InStr)+Counter);
for(Counter=0;Counter<LenReplaceWith; Counter++)
*(NewString+From+Counter)=*(ReplaceWith+Counter);
for(Counter=To+1, k=0; Counter<Len; Counter++, k++)
*(NewString+From+LenReplaceWith+k)=*((*InStr)+Counter);
*(NewString+From+LenReplaceWith+k)=0;
free(*InStr);
Len=strlen(NewString);
*InStr=(char*)malloc(sizeof(char)*(Len+1));
if((*InStr)==NULL) return -1;
strcpy(*InStr, NewString);
free(NewString);
return (From-1+LenReplaceWith);
}
char* SubString(char* Source, const int From, const
To)
{
int Len, Counter;
char *NewString;
Len=strlen(Source);
if(Source==NULL) return NULL;
if (From<0) return NULL;
if (From>To) return NULL;
if ((From>Len) || (To>Len)) return NULL;
NewString=(char*)malloc(sizeof(char)*(To-From+2));
for(Counter=From; Counter<=To; Counter++)
{
*(NewString+Counter-From)=*(Source+Counter);
}
NewString[Counter-From]=0;
return NewString;
}
void Reverse(char* Str)
{
int i, j, len;
char temp;
i=j=len=temp=0;
if(Str!=NULL)
{
len=strlen(Str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=Str;
Str=Str[j];
Str[j]=temp;
}
}
}
//File R.C
#include "R.h"
int main(void)
{
char c, *InStr, *ReplaceWith;
int i;
c=' ';
i=0;
InStr=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(InStr==NULL) return -1;
ReplaceWith=(char*)malloc(sizeof(char)*(MAX_LEN+1));
if(ReplaceWith==NULL) return -1;
printf("\nEnter a string (1000 characters maximum):");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN)) InStr[i++]=c;
InStr=0;
c=' ';
i=0;
printf("\n\nEnter the string that you wish to replace\npallindromes
with (1000 characters maximum): ");
while(((c=getchar())!=EOF) && (c!='\n') & (i<=MAX_LEN))
ReplaceWith[i++]=c;
ReplaceWith=0;
if(ReplacePallindromes(&InStr, ReplaceWith)==0)
{
printf("\nThe modified string is:\n\n %s\n", InStr);
}
else
{
printf("An error occured. The program will now end.");
free(InStr);
free(ReplaceWith);
return -1;
}
free(InStr);
free(ReplaceWith);
return 0;
}
I was asked as to why I'd taken a pointer to a pointer as the first
argument of the ReplacePallindrome function. I thought I'd write a
tutorial to explain this thing that I'd arrived at by heuristic
endeavours in the past, when I practiced pointers. So here's a
tutorial I've written. Even at the risk of being laughed at, I present
it to all of you learned people out here, so you may review it,
because, with a few refinements, I intend to get it published if it is
all ok. I am only learning C and thus have written only what I've
coded and tested with my own hands. Please give me your comments as to
how good or bad it is.
http://sathyaishc.tripod.com/Tutorial.doc
(You have to do a right-click and say "Save As" or "Save Target As")
Thanks!