繁体   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