2

再会!我们的老师要求我们确定一个单词或一系列数字是否是回文或不使用堆栈。我已经完成了。但是我想练习更多所以现在我试图通过删除空格和其他不相关的字符来确定一个句子是否是回文(注意:不再是我的家庭作业的一部分)我的代码已经在工作(希望如此)但我发现它很乱。所以我想改进它。我想删除 goto 功能,因为我的老师建议我不要使用它。如何使用 goto 函数退出 if 语句?先感谢您。还有其他方法可以检查一个句子是否是回文,因为我的代码是用蛮力方法完成的。我的代码如下:注意(我没有在此处包含/粘贴结构以及弹出和推送功能)

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();
}

根据您的建议。这是我改进的代码:

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();
}
4

4 回答 4

4

您可以进行的最简单的更改如下:

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

您还可以做一些其他的事情来整理代码(例如,合并if语句,去掉isspace因为!isalpha覆盖了,等等)。

于 2010-12-13T13:03:51.400 回答
2

我喜欢你的态度。

首先,您在这里尝试做的是嵌套两个本质上是一个的逻辑语句。您还使用了错误的函数来确定字符类型:

如果isspace(word[i])那么你可以保证!isalpha(word[i])。这两个陈述总是同时为真或假,因此其中一个是多余的。你真正在做的只是在字母数字的情况下推动字符,对吗?因此,与其使用 if 语句来确定是否要跳过字符,不如使用 if 语句来确定是否要推送字符。我想isalnum()可能是你想要的。

其次,不要执行 strlen() 迭代字符串并使用返回值迭代字符串(这使得两次)尝试:

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

甚至更好:

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

最后,您的回文测试可以稍微整理一下。在循环之后测试循环值在所有情况下都有效,但有点难看。它也不会甘愿忍受傻瓜。在专业环境中,您会遇到很多人,有些人不那么认​​真,他们编辑代码并在循环后使用循环值可能会有风险。也许取而代之的是一个名为“match”的bool并将其初始化为true,然后循环直到堆栈结束或“match”变为false并将“match”设置为false,如果堆栈上的字符不“匹配”期望值。这也会更有效率。


当原始问题显然被删除时,我正在撰写此答案。

如果您希望我发布代码示例,我很乐意这样做,但我认为如果我不这样做,您可能会学到更多。如果你想要一个代码示例,或者想让我看看你在这个答案之后想出什么,请随意。

于 2010-12-13T13:03:44.357 回答
1

我只是扫了一眼..可能是误解:

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

   }
   i++;

}

于 2010-12-13T13:11:02.560 回答
0

对于这么短的跳转,重写以消除问题是微不足道的。

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++;
}
于 2010-12-13T13:05:44.197 回答