0

これは学校の宿題です。私は正しい答えを求めているのではなく、正しい方向へのプッシュを求めているだけです。なぜこれがうまくいかないのかについての説明は、正しい方法の説明と同様に素晴らしいでしょう. この C プログラムが行うべきことは、ユーザー入力をスペースや句読点なしで読み取り、それを文字配列 string に割り当てることです。次に、この配列を関数 palindrome に渡す必要があります。回文は文字列の長さである必要があり、1 または 0 のいずれかに等しい場合は TRUE を返すか、そうでない場合は 1 を返し、文字列の最初と最後の文字をチェックします。それらが一致する場合、2 番目と 2 番目から最後までの文字、およびその間のすべての文字を取得し、それを関数 palindrome に渡します。

#include<stdio.h>
#include<ctype.h>
#include<string.h>

#define TRUE 1
#define FALSE 0
typedef int Bool;

Bool palindrome(char str[]);
main()
{
char string[1000], ch;
int i = 0;

printf("Enter a message: ");
while((ch = getchar()) != '\n'){
  if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
    string[i] = tolower(ch);
    i++;
}

string[i] = '\0';

printf("\n");
if(palindrome(string))
  printf("Palindrome\n");
else
  printf("Not a palindrome\n);

return 0;
}

Bool palindrome(char str[])
{
   int length = strlen(str);
   if((length == 1) || (length == 0))
     return TRUE;
   else
   {
     if((str[0] == str[length - 1])
       {
         char str_new[length-1];
         int i, j;
         for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)
           str_new[j] = str[i];

         str_new[i] = '\0';
         palindrome(str_new);
       }
       else
         return FALSE;

   }
}

入力が何であれ、与えられた文字列が回文ではないことを常に出力します。たとえば、私が入力したとき

彼は悪魔として生きていましたね。

それは印刷されます

回文ではない

また、プログラムを編集して、前の入力を使用して配列文字列に何があったかを確認すると、

彼は悪魔として生きていましたね。

コード使用の改善が見られる私のコードの他の側面について自由にコメントしてください。彼らは本当に、はい、その権利があるか、私たちのコードには関係ないという以外には何も提供していません。

編集:
char配列stringの値が何であるかを確認しました。最後の引用の前にこれを言います。

4

3 に答える 3

1
if(isspace(ch)==FALSE || ispunct(ch)==FALSE);

これはあなたの間違いです。;まず、最後にセミコロン()を付けないでください。

次に、ORを使用するのではなく、ANDを使用する必要があります。これは、アルファベット以外のすべてをフィルタリングしていることを確認するためです。

if(isspace(ch)==FALSE && ispunct(ch)==FALSE)

また:

for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)

ここでは、ブール式が間違っています。あなたは評価する必要がありますj

for(i = 1, j = 0; j < length - 1; i++, j++)

最後に、i++新しい文字列に文字を追加しているときのステートメントの位置が正しくありません。スペースを空けて、whileループの本体の一部であり、ifブロックの外側にある必要があることをコンパイラーが認識できるようにします。

于 2013-03-23T16:53:20.317 に答える
1

ここを見てください...

while((ch = getchar()) != '\n'){
  if(isspace(ch)==FALSE || ispunct(ch)==FALSE);
    string[i] = tolower(ch);
    i++;
}

「;」に注意してください if文の最後に。それか ';' string[i] = tolower(ch) を常に実行させています。さらに、ロジックが正しくありません。文字が空白ではなく、句読点でもない場合にコードを実行する必要があります。

さらに、インデントに注意してください。i++ も if ステートメント内にある必要がありますが、中かっこがありません。したがって、「;」を削除しても、i++ は常に実行されます。そう...

while((ch = getchar()) != '\n'){
  if(isspace(ch)==FALSE && ispunct(ch)==FALSE)
  {
    string[i] = tolower(ch);
    i++;
  }
}

または...さらに良い...

while((ch = getchar()) != '\n'){
  if(isspace(ch)==FALSE && ispunct(ch)==FALSE)
    string[i++] = tolower(ch);
}

スタイル コメントも同様です...メンテナンスと読みやすさのために、関数から単一の出口点を持つことは多くの場合良い考えです。他の人はそこで別の議論をするかもしれませんが、それは私が国防総省の仕事をしてきた過去 30 年間生きてきた厳しい規則です。読みやすさのためにこれを見て、それがあなたにとってより意味があるかどうかを確認してください.

Bool palindrome(char str[])
{
   Bool result = TRUE;
   int length = strlen(str);

   if( length > 1 && str[0] == str[length-1] )
   {
     char str_new[length-1];
     int i, j;

     for(i = 1, j = 0; str[i]!=str[length-1]; i++, j++)
        str_new[j] = str[i];

     str_new[i] = '\0';
     result = palindrome(str_new);
   }

   return result;
}

最後に...効率の観点から、文字列をコピーするのではなく、簡単にインデックスを付けることができます...

Bool palindrome(char str[])
{
    Bool result = TRUE;
    int length = strlen(str);

    if( length > 1 && str[0] == str[length-1] )
    {
       str[length-1] = '\0';
       result = palindrome(&str[1]);
    }

    return result;
}
于 2013-03-23T16:51:56.333 に答える
0

いくつかの明らかなポイント:

  • 問題のコードはコンパイルされません。
  • あなたの主な宣言は標準ではありません。
  • ステートメントのif行末に誤ったセミコロンがあります。
  • ifステートメントのロジックが正しくありません。文字はスペースと句読点の両方にすることはできないため、論理またはテストは常にtrueと評価されます。
  • 回文チェック機能は、必要以上に複雑です。

重要な変更は、ifステートメントが次のようになることです。

if (!isspace(ch) && !ispunct(ch))

完全に機能するプログラムは次のようになります。

#include<stdio.h>
#include<string.h>

#define TRUE 1
#define FALSE 0
typedef int Bool;

Bool palindrome(char str[]);

int main(void)
{
    char string[1000], ch;
    int i = 0;

    printf("Enter a message: ");
    while((ch = getchar()) != '\n'){
        if (!isspace(ch) && !ispunct(ch))
        {
            string[i] = tolower(ch);
            i++;
        }
    }

    string[i] = '\0';
    printf("string = %s\n", string);
    if(palindrome(string))
        printf("Palindrome\n");
    else
        printf("Not a palindrome\n");

    return 0;
}

Bool palindrome(char str[])
{
   int left = 0;
   int right = strlen(str)-1;
   while (left<right)
   {
       if(str[left] != str[right])
           return FALSE;
       left++;
       right--;
   }
   return TRUE;
}

出力は次のとおりです。

メッセージを入力してください:彼は悪魔として生きていましたね?
文字列=helivedasadevileh
回文
于 2013-03-23T16:58:40.400 に答える