سؤال

Good day! Our teacher required us to determine if a word or a series of number is a palindrome or not using stacks. I already finished doing that. But I want to practice more so right now I am trying to determine if a sentence is a palindrome or not by removing whitespaces and other irrelevant characters (Note: Not part of my homework anymore) My code is already working (hopefully) but I find it messy. So i want to improve it. I want to remove the goto function because my teacher advised me not to use it. How can i go out of the if statement w/o using the goto function? Thank you in advance. Also are there other ways to do check if a sentence is a palindrome or not because my code is done in a brute force method. My code is as follows: NOTE(I did not include/pasted the struct and the pop and push function here)

int main(){
   char word[11];
   char temp[11];
   char value;
   int i=0, x=0, n=0, length=0; 
   Stack*head = NULL;
   printf("Please type the word: ");
   gets(word);
   length = strlen(word);
   while(i<length){
       if(isspace(word[i]) || !isalpha(word[i]))  {
           if(isdigit(word[i])) goto NEXT;  // i used the goto function here
           i++; 
           continue;
       }
       NEXT:
       temp[n]=word[i];
       push(&head, word[i]);
       i++;
       n++;
   }
   temp[n]='\0';
   while(x<n){
       value = pop(&head);         
       if (value==temp[x]){ 
           x++; 
           continue;
       }
       break;
   }    
   if(x==n) printf("Yehey! It is a palindrome.");
   else printf("Sorry, It is not a palindrome.");
   getch();
}

Based from your suggestions. Here is my improved code:

int main(){
   char word[11];
   char temp[11];
   int i=0, n=0; 
   int flag = 1;
   Stack*head = NULL;
   printf("Please type the word: ");
   fgets(word, 11, stdin);
   for(i = 0; word[i]!='\0' ; i++){
       if(isalnum(word[i])) {
           temp[n]=word[i];
           push(&head, word[i]);
           n++;
       }
   }
   temp[n]='\0';
   for(i=0; temp[i]!='\0'; i++){
       if (pop(&head)!=temp[i]){ 
          flag = 0;
          break;
       }
   }    
   if (flag==1) printf("Yehey! It is a palindrome.");
   else printf("Sorry, It is not a palindrome.");
   getch();
}
هل كانت مفيدة؟

المحلول

I like your attitude.

Firstly, what you are trying to do here is nest two logic statements that are essentially one. You are also using the wrong functions to determine the character type:

if isspace(word[i]) then you can guarantee that !isalpha(word[i]). Both statements will always be true or false at the same time so one of them is redundant. What you are really doing is only pushing characters if the are alphanumeric, right? So rather than having an if statement to determine if you want to skip a character you ought to be doing an if statement to determine if you want to push the character. I think isalnum() might be what you want.

Secondly, rather than doing strlen() which iterates over the string and using the return value to iterate over the string (that makes twice) try:

while('\0' != word[i])

or even better:

for(i = 0; '\0' != word[i]; i++)

Lastly, your test for a palindrome could be neatened up a bit. Testing a loop value after the loop works in all cases but is a bit ugly. It also does not suffer fools gladly. In a professional environment you get many people, some not so conscientious, editing the code, and using loop values after a loop can be risky. Maybe instead have a bool called something like "match" and initialise it to true, then loop until end of the stack or "match" turns false and set "match" to false if the character on the stack doesn't "match" the expected value. This will also be more efficient.


I was in the middle of composing this answer when the original question apparently got deleted.

If you want me to post a code example I'm happy to do so, but I think you might learn more if I don't. If you want a code example, or want me to have a look at what you come up with after this answer, feel free.

نصائح أخرى

The simplest change you can make is the following:

   ...
   if(isspace(word[i]) || !isalpha(word[i]))  {
       if(!isdigit(word[i])) {
           i++; 
           continue;
        }
   }
   temp[n]=word[i];
   ...

There are a few other things you can do to tidy up the code (e.g. combine the if statements, get rid of the isspace since !isalpha covers that and so on).

I just glanced over..might be misunderstanding:

while(i<length){
   if(isalnum(word[i]))  {
       temp[n]=word[i];
       push(&head, word[i]);
       n++;

   }
   i++;

}

For such a short jump, it's trivial to re-write to remove the problem.

while(i<length){
   if(isspace(word[i]) || !isalpha(word[i]))  {
       if(!isdigit(word[i])) {
           i++;
           continue;
       }
   }
   temp[n]=word[i];
   push(&head, word[i]);
   i++;
   n++;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top