簡體   English   中英

如何計算字符串中回文詞的數量?

[英]How to count the number of words that are palindromes in a string?

我顯然是新來的論壇,需要一些幫助。 我正在寫一個程序,顯示一個句子中的元音,單詞和回文的數量。 我已經走到了盡頭,完全迷失了。

我正在使用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;
}

以下代碼已經過測試。 請根據需要更正或下注。 如果代碼格式無效,請道歉。 我將給你一個我剛剛放在一起的例子。 它可能不完全符合您的要求,但它應該讓您開始。 然后我將解釋我的代碼是如何工作的,並給出一些修改代碼的指示。

#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時,我們會使用這些數學屬性。 這在使用字符時並不重要,但是當您進入其他數據類型時,從元素移動到元素將非常有用。 另外,如果您注意到,我的所有變量都有明確的標簽。 同樣,這將有助於代碼可讀性和可維護性。 如果上面的代碼不夠,請隨時告訴我,我會盡力詳細說明具體問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM