0

私は明らかにフォーラムに不慣れで、助けが必要です。文中の母音、単語、回文の数を表示するプログラムを書いています。私はロープの終わりにいて、完全に迷っています。

私は C を使用しており、入力内の単語をループして、文に含まれる回文の数を判断しようとしています。これはカウンター内に保存され、後でメイン メソッド内に出力されますが、作成には支援が必要です上記のループは、カウンターに値を適切に格納するためのものです。

これが私がこれまでに持っているものです(私は特に見ていint is_palindrome(char my_sen[])ます)

        #include <stdio.h>
        #include <string.h>
        #include <ctype.h>
        #define SENTENCE 256


        int main(void){

        char my_sen[SENTENCE],*s; //String that containts at most 256 as well as a pointer
        int words = 1, count = 0, pal_count= 0; //Integer variables being defined
        int i,vowel = 0, length;  //More definitions
        printf("Enter a sentence: ");//Input sentence
        gets(my_sen);//Receives and processes input
        length = strlen(my_sen); //Stores the length of the input within length

        for(i=0;my_sen[i] != '\0'; i++){
            if(my_sen[i]=='a' || my_sen[i]=='e' || my_sen[i]=='i' || my_sen[i]=='o' || my_sen[i]=='u' || //Loop that states if the input contains any of the following
               my_sen[i]=='A' || my_sen[i]=='E' || my_sen[i]=='I' || my_sen[i]=='O' || my_sen[i]=='U')   //characters(in this case, vowels), then it shall be
               {                                                                                         //stored to be later printed
                   vowel++;
               }


            if(my_sen[i]==' ' || my_sen[i]=='!' || my_sen[i]=='.' || my_sen[i]==',' || my_sen[i]==';' || //Similar to the vowel loop, but this time
                my_sen[i]=='?')                                                                          //if the following characters are scanned within the input
                {                                                                                        //then the length of the characters within the input is
                    length--;                                                                            //subtracted
        }
        }

        for(s = my_sen; *s != '\0'; s++){ //Loop that stores the number of words typed after
            if(*s == ' '){                //each following space
            count++;
        }
        }



        printf("The sentence entered is %u characters long.\n", length); //Simply prints the number of characters within the input
        printf("Number of words in the sentence: %d\n", count + 1); // Adding 1 to the count to keep track of the last word
        printf("Average length of a word in the input: %d\n", length/count);//Prints the average length of words in the input
        printf("Total Number of Vowels: %d\n", vowel);//Prints the number of vowels in the input
        printf("Average number of vowels: %d\n", vowel/count);//Prints the average number of vowels within the input
        printf("Number of words that contain at least 3 vowels: %d\n",vowel_count(my_sen));//Prints number of words that contain at least 3 vowels
        printf("Number of words that are palindomes: %d\n", is_palindrome(my_sen));
        return 0;
        }

        int vowel_count(char my_sen[])
        {
          int wcount = 0; 
          int vcount = 0; 
          int i = 0;
          int ch;
          while ((ch = my_sen[i++]) != '\0')
          {
            if (isspace(ch) || !isalpha(ch))
            {
              wcount += vcount >= 3; 
              vcount = 0; 
              continue;

            if (strchr("aeiouAEIOU", ch) != NULL) 
            {
              ++vcount; 
            }
          }

          wcount += vcount >= 3; // add 1 to wcount if vcount >= 3
          return wcount;
        }


int is_palindrome(char my_sen[]){
  int begin, middle, end, length = 0, result = 0, pal = 0; //variables representing the string length, beginning, middle, and end of string

   while ( my_sen[length] != '\0' ) //loop to define and initialize variables
      length++;

   end = length - 1; //end is the end of the length
   middle = length/2;//middle is half the length

   for( begin = 0 ; begin < middle ; begin++ )
   {
      if ( my_sen[begin] != my_sen[end] ) //if the beginning isn't equal to the end, then it's not a palindrome
      {
        result += pal;
         pal = 0;
         continue;
      }
      end--;
   }
   if( begin == middle ) //if the beginning is the same as the middle, its a palindrome
      pal++;
      result += pal;
      return result;
}
4

1 に答える 1

2

以下のコードはテスト済みです。必要に応じて修正または反対票を投じてください。コードのフォーマットが無効である場合はお詫び申し上げます。頭のてっぺんから、私がまとめた例を挙げます。それはあなたの要件に完全に一致していないかもしれませんが、開始する必要があります. 次に、私のコードがどのように機能するかを説明し、コードを変更するためのヒントをいくつか示します。

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

int main()
{
int i,vowels,pals,words;
vowels=words=pals=i=0;
long max=1024;
char *sentence=malloc(sizeof(char)*max);
printf("sentence:");
fgets(sentence,max,stdin);
if (sentence[strlen(sentence)-1]=='\n')
{
sentence[strlen(sentence)-1]='\0';
}
for (i=0;i<=strlen(sentence);i++)
{
char x;
x=sentence[i];
switch (x)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
vowels+=1;
}
if ((x==' '||x=='\0') && i>0 && sentence[i-1]!=' ')
{
words+=1;
}
if (i>0 && (x=='\0'||x==' '))
{
char *lastchar,*pos,*word;
lastchar=sentence+i;
pos=(sentence+i)-1;
while (*pos!=' ' && pos!=sentence)
{
pos--;
if (*pos==' ')
{
pos++;
break;
}
}
word=strndup(pos,lastchar-pos);
if (isSameStringReversed(word)==0)
{
pals+=1;
}
free(word);
} //if on space for pal
} //for
printf("vowels:%d words:%d pals:%d\n",vowels,words,pals);
free(sentence);
}

int isSameStringReversed(char *word)
{
int i;
char destword[strlen(word)+1];
int j;
for (i=strlen(word)-1,j=0;i>=0;i--,j++)
{
destword[j]=word[i];
}
return strncmp(word,destword,strlen(word));
}
</pre>

次に、いくつかのコードの説明です。

//here are our includes. nothing special.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main()
{
//defines
int i,vowels,pals,words;
long max;
//set all to zero. (an empty sentence has no words.)
vowels=words=pals=i=0;
//max is the largest sentence you can enter
max=1024;
//allocate space for the sentence in memory.
char *sentence=malloc(sizeof(char)*max);
//prompt for sentence
printf("sentence:");
//read characters from stdin, making sure that only the first 1023 characters are read. (fgets removes the last character(s) if it is greater or equal to the provided limit. e.g. providing 1024 means that all characters past character 1023 are removed, and a \0 is appended to sentence.)
fgets(sentence,max,stdin);
//check last character of sentence for \n character, as some calls leave newlines attached.
if (sentence[strlen(sentence)-1]=='\n')
{
//set the last character to \0 if newline found. \0 terminates strings in c.
sentence[strlen(sentence)-1]='\0';
}
//move through every character in the sentence, including the terminating \0 character. This way, we make sure we pass every word and character provided, and we don't have to check at the end of loops for remaining characters.
for (i=0;i<=strlen(sentence);i++)
{
//defines for this for loop
char x;
//pull the current character from sentence. this way, we don't ahve to do sentence[i] each time.
x=sentence[i];
//switch is like an extended if statement with lots of possible branches.
switch (x)
{
//if x, the current character, equals 'a'
case 'a':
//if x, the current character, equals uppercase 'A'
case 'A':
//etc for the rest of the variables (excluding the sometimes cases of 'y')
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
//if x equals any of the above letters, then
//we add one to vowels, since our current letter is a vowel.
vowels+=1;
}
//if our current character is a space character, or a \0, meaning the end of our sentence string,
//and we are not on our first character, (because our sentence is not empty), and the character before our current character is not a space (because we don't count double spaces as words)
if ((x==' '||x=='\0') && i>0 && sentence[i-1]!=' ')
{
//it's a word, so add one to the words count
words+=1;
}
//again, if we are on a space or at the end of our string,
if (i>0 && (x=='\0'||x==' '))
{
//defines
char *lastchar,*pos,*word;
//lastchar is a pointer to where we are currently sitting (on the space or end character of the string)
lastchar=sentence+i;
//pos is a pointer to the previous character
//say we have
//A bunny likes racecar races.
//if we are on the space just after racecar, then lastchar points to the space, and pos points to the r in racecar
pos=(sentence+i)-1;
//while the character that pos points to isn't a space, and we aren't at the beginning of the string
while (*pos!=' ' && pos!=sentence)
{
//move the pointer pos back one character
pos--;
//if we're on a space, we've moved back before the previous word.
if (*pos==' ')
{
//we want to move pos to the first character of the preceding word.
pos++;
break;
}
}
//make a new copy of the current word, which we do by using strndup, analagus to (duplicate string with only n number of characters).
//we take the value of pos, and subtract it from lastchar, which gives us the length of the preceeding word.
//we used racecar as our example, so the space after racecar, minus the position of the r, gives us 7, which is the amount that strndup copys.
word=strndup(pos,lastchar-pos);
//if the function below returns 0
if (isSameStringReversed(word)==0)
{
//we've found a palindrome
pals+=1;
}
//free word, a.k.a. the chunk of memory we created for checking the last word as a palindrome.
free(word);
} //endif palindrome boundary check
} //endfor character in sentence loop
//print the character vowel and palindrome counts
printf("vowels:%d words:%d pals:%d\n",vowels,words,pals);
//free the sentence, as we're done with it.
free(sentence);
}

//function
//word is a pointer to char, or an array of characters. In this case word points to "word" defined above,
//or "racecar" from our example.
int isSameStringReversed(char *word)
{
//defines
//take the length of the provided word, and add a character to it for the \0, or ending character.
char destword[strlen(word)+1];
int i;
int j;
//set i to the number of the last character in word, and j to 0.
//move through the string, subtracting one from i and adding one to j.
for (i=strlen(word)-1,j=0;i>=0;i--,j++)
{
//move from right to left, assigning word to destword in reverse order.
//racecar would take the last r, assign it to the first slot in destword, the second to last a to the second position, and so on.
destword[j]=word[i];
//continue the loop
}
//see if the two reversed strings match, with strncmp.
return strncmp(word,destword,strlen(word));
}

説明。最後の関数を除くすべての場所でポインターを使用していることに注意してください。これには正当な理由があります。ポインターは柔軟性があり、理解しやすく、数学的な操作が可能です。また、それらは迅速で、コードの可読性にも役立ちます。お気づきかもしれませんが、lastchar から pos を減算するときに、これらの数学的プロパティを使用します。これは、char を使用する場合はそれほど重要ではありませんが、他のデータ型を使用する場合は、要素から要素への移動が非常に役立ちます。また、お気付きのように、すべての変数に明確なラベルが付けられています。繰り返しますが、これはコードの可読性と保守性に役立ちます。上記のコードで十分でない場合は、お気軽にお知らせください。特定の問題について詳しく説明できるよう最善を尽くします。

于 2012-10-02T04:19:37.097 に答える