1

ユーザーからの文入力を取得し、単語を逆順に出力し、アナグラムをチェックし、回文をチェックする必要があるという課題に取り組んでいます。アナグラムで機能する関数があり、回文関数がほとんど機能しています。今のところ、関数を機能させるために 2 つの単語だけを求めています。しかし、どういうわけか、私が要求する両方の単語に対して長い回文 (例: レースカーまたは母または父と比較して不機嫌) を入力するたびに、回文機能が台無しになります。

コードは次のとおりです。

#include <stdio.h>
#include <ctype.h> //Included ctype for tolower / toupper functions
#define bool int
#define true 1
#define false 0

//Write boolean function that will check if a word is a palindrome
bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++;

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }

    c = 0;

    while(a[c])
    {
        printf("%c", d[c]);
        printf("%c", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {
        while(a[c] && d[c])
        {
        if(a[c] != d[c])
            return false;
        }
    }
    return true;
}

int main(void)
{
    char a[80], b[80];
    bool flagp;
    //Prompt user to enter sentence
    printf("Enter a word: ");
    gets(a);

    flagp = palindrome(a);

    if (flagp)
    {
        printf("\nThe word is a palindrome.");
    }
    else
    {
        printf("\nThe word is not a palindrome.");
    }

    return 0;
}

これを出力します。

Enter first word: racecar
_r▬a↨c e c a r
The word is not a palindrome.

ただし、「racecar」と入力すると、回文ではないと誤って示されます。

私が間違っていることを教えてください:'(

4

2 に答える 2

2
  1. a[c] != d[c]であると期待するときは真です。
  2. あなたはこれがガベージprintfであるためであることをあなたで示しました。d[c]
  3. つまりd、 の逆は含まれませんa
  4. したがって、これにより、次のスニペットを調べることができます。

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }
    

    反転コピーを作成しようとしていますが、取っているのと同じインデックスに配置しているため、明らかに反転に失敗しています。

(最初の 3 つのステップを完了しました。なぜそこで停止したのですか?)

正直なところ、 to が存在する理由はまったくありませんd。すべてインプレースで実行できます。

   +---+---+---+---+---+---+---+
a: | r | a | c | e | c | a | r |
   +---+---+---+---+---+---+---+
     ^                       ^
     |   compare these two   |


         ^               ^
         |  then these   |


                ...

したがって、コードは次のようになります。

size_t len = strlen(a);
if (len) {
   size_t i = 0;
   size_t j = len - 1;
   while (i < j) {
      if (a[i++] != a[j--])
         return 0;
   }
}

return 1;

ノート:

  1. しないで#define true 1ください#define false 0。これらは C の定義とは異なるため、 のif (b == true)代わりに使用すると間違った結果が得られる可能性がありif (b)ます。

  2. c通常、 は a を表しますchari(およびjおよびk) は、より一般的にインデックスに使用されます。

于 2013-10-12T23:57:49.923 に答える
1

問題はあなたのpalindrome機能にあります。スニペットで

while(a[c] != 0 && c > -1)
{
    d[c] = a[c];
    c--;
}

あなたは逆転していませんa

そしてスニペット

while (a[c])
    c++;  

cによって範囲外に出る原因となり1ます。

これらの問題を修正しました。変更したコード:

bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++; 
        c=c-1; // Number of elements in a is one less than that of counter c.

    int i = 0;  // taking another counter for array d
    while(a[c] != 0 && c > -1)
    {
        d[i] = a[c];
        i++;
        c--;
    }
    d[i] = '\n'; // last element of array mut be a nul char
    c = 0;

    while(a[c])
    {
        printf(" %c\t", d[c]);
        printf(" %c\n", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {

         if(a[c]  != d[c] )
            return false;

    }
    return true;
}  

結局のところ、この関数は回文のチェックには十分ではありません。例:

入力:

I am a     I

あなたが得る

The word is not a palindrome.  
于 2013-10-13T00:24:33.150 に答える