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

私はあなたの態度が好きです。

まず、ここで実行しようとしているのは、本質的に1つである2つの論理ステートメントをネストすることです。また、文字タイプを判別するために間違った関数を使用しています。

もしそうならisspace(word[i])、あなたはそれを保証することができます!isalpha(word[i])。両方のステートメントは常に同時にtrueまたはfalseになるため、一方が冗長になります。あなたが実際に行っているのは、英数字の場合にのみ文字をプッシュすることですよね?したがって、文字をスキップするかどうかを決定するifステートメントを使用するのではなく、文字をプッシュするかどうかを決定するifステートメントを実行する必要があります。私はisalnum()あなたが望むものかもしれないと思います。

次に、文字列を反復処理するstrlen()を実行し、戻り値を使用して文字列を反復処理する(2回実行する)のではなく、次のことを試してください。

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

またはさらに良い:

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

最後に、回文のテストが少し必要になる可能性があります。ループの後にループ値をテストすることはすべての場合に機能しますが、少し醜いです。それはまた喜んで愚か者に苦しむことはありません。プロフェッショナルな環境では、多くの人が参加しますが、あまり良心的ではない人もいます。コードを編集したり、ループの後にループ値を使用したりするのは危険です。代わりに、「match」のようなブール値を使用してtrueに初期化し、スタックの最後までループするか、スタック上の文字が「match」でない場合は「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 に答える