C 计算文件中音节数的程序

C 计算文件中音节数的程序,c,arrays,loops,C,Arrays,Loops,我有一个函数,在给定这些约束条件的情况下,它应该计算文件中的音节数: 1) 每组相邻元音(a、e、i、o、u、y)算作一个音节(例如,“real”中的“ea”算作一个音节,“regal”中的“e..a”算作两个音节) 2) 单词末尾的“e”不能算作音节 3) 即使前面的规则给出的计数为零,每个单词至少有一个音节 考虑到这一点,我创建了(尽管是一个相当糟糕的)函数来计算文件中音节的数量 我尝试过用许多不同的方法创建这个函数,但这种方法对我来说最有意义,也给了我对真实答案的合理估计(不是真的,但从它

我有一个函数,在给定这些约束条件的情况下,它应该计算文件中的音节数:

1) 每组相邻元音(a、e、i、o、u、y)算作一个音节(例如,“real”中的“ea”算作一个音节,“regal”中的“e..a”算作两个音节)

2) 单词末尾的“e”不能算作音节

3) 即使前面的规则给出的计数为零,每个单词至少有一个音节

考虑到这一点,我创建了(尽管是一个相当糟糕的)函数来计算文件中音节的数量

我尝试过用许多不同的方法创建这个函数,但这种方法对我来说最有意义,也给了我对真实答案的合理估计(不是真的,但从它所做的宏伟计划来看)

int syllableCount(char **str)
{
    int i = 0;
    int q = 0;
    int syllableCounter = 0;

    for (i = 0; i < lineCount; i++)
    {
        for (q = 0; q <= strlen(str[i]); q++)
        {
            if (str[i][q] == 'A' || str[i][q] == 'a' ||
                str[i][q] == 'E' || str[i][q] == 'e' ||
                str[i][q] == 'I' || str[i][q] == 'i' ||
                str[i][q] == 'O' || str[i][q] == 'o' ||
                str[i][q] == 'U' || str[i][q] == 'u' ||
                str[i][q] == 'Y' || str[i][q] == 'y')
            {
                syllableCounter++;
            }
            if ((str[i][q] == 'E' && str[i][q + 1] == ' ') ||
                (str[i][q] == 'e' && str[i][q + 1] == ' ') ||
                (str[i][q] == 'E' && str[i][q + 1] == '\n') ||
                (str[i][q] == 'e' && str[i][q + 1] == '\n') ||
                (str[i][q] == 'E' && str[i][q + 1] == '.') ||
                (str[i][q] == 'e' && str[i][q + 1] == '.') ||
                (str[i][q] == 'E' && str[i][q + 1] == ';') ||
                (str[i][q] == 'e' && str[i][q + 1] == ';') ||
                (str[i][q] == 'E' && str[i][q + 1] == ':') ||
                (str[i][q] == 'e' && str[i][q + 1] == ':') ||
                (str[i][q] == 'E' && str[i][q + 1] == '!') ||
                (str[i][q] == 'e' && str[i][q + 1] == '!') ||
                (str[i][q] == 'E' && str[i][q + 1] == '?') ||
                (str[i][q] == 'e' && str[i][q + 1] == '?'))
            {
                syllableCounter--;
            }
            if ((str[i][q] == 'A' || str[i][q] == 'a' ||
                 str[i][q] == 'E' || str[i][q] == 'e' ||
                 str[i][q] == 'I' || str[i][q] == 'i' ||
                 str[i][q] == 'O' || str[i][q] == 'o' ||
                 str[i][q] == 'U' || str[i][q] == 'u' ||
                 str[i][q] == 'Y' || str[i][q] == 'y') &&
                (str[i][q + 1] == 'A' || str[i][q + 1] == 'a' ||
                 str[i][q + 1] == 'E' || str[i][q + 1] == 'e' ||
                 str[i][q + 1] == 'I' || str[i][q + 1] == 'i' ||
                 str[i][q + 1] == 'O' || str[i][q + 1] == 'o' ||
                 str[i][q + 1] == 'U' || str[i][q + 1] == 'u' ||
                 str[i][q + 1] == 'Y' || str[i][q + 1] == 'y'))
            {
                syllableCounter--;
            }
            if ((str[i][q] != 'A' || str[i][q] != 'a' ||
                 str[i][q] != 'E' || str[i][q] != 'e' ||
                 str[i][q] != 'I' || str[i][q] != 'i' ||
                 str[i][q] != 'O' || str[i][q] != 'o' ||
                 str[i][q] != 'U' || str[i][q] != 'u' ||
                 str[i][q] != 'Y' || str[i][q] != 'y') &&
                (str[i][q + 1] == ' ' || str[i][q + 1] == '\n'))
            {
                syllableCounter++;
            }
        }
    }
    return syllableCounter;
}
int音节计数(字符**str)
{
int i=0;
int q=0;
国际音节计数=0;
对于(i=0;i对于(q=0;q来说,您的代码太复杂了

原始问题陈述中的规则非常简单。对于每个单词,您需要计算遇到多少不同的元音组。注释中使用状态机的建议绝对正确。但是,您不需要复杂的机器。您只需要跟踪几个基本状态

至少,我建议以下国家:

int in_word = 0;         // non-zero if currently processing a word
int in_vowels = 0;       // non-zero if currently processing group of vowels
int is_silent_e = 0;     // non-zero if the last vowel processed was an 'e'
int vowel_groups = 0;    // counts the number of vowel groups encountered in current word
现在,对于如上所述的合理状态,下面是如何使用它们的概要:

for (char *p = str[i], *end = p + strlen(str[i]) + 1; p != end; ++p)
{
    char c = tolower(*p);
    if (isalpha(c))
    {
        // starting a new word?
        if (!in_word) {
            in_word = 1;
            in_vowels = 0;
            is_silent_e = 0;
            vowel_groups = 0;
        }

        // do we have a vowel?
        if (strchr("aeiouy", c)) {
            if (!in_vowels) {
                /**** WRITE ME ****/
                ++vowel_groups;
            } else {
                /**** WRITE ME ****/
            }
        } else if (in_vowels) {
            // no longer in vowel group
            /**** WRITE ME ****/
        }
    }
    else if (in_word)
    {
        // No longer in a word -- update syllable count and reset
        vowel_groups -= is_silent_e;

        /**** WRITE ME ****/
    }
}
我给您留下了一些逻辑供您填写。当您正确填写时,您将得到示例输入的答案
32


注意特殊的循环条件,它确保字符串的空终止符也被循环处理。这将确保即使字符串中的最后一个字符是单词字符,也可以运行词尾测试。

您可以考虑制作状态机。可以在调试器中通过代码吗?试着跟随它到MAK。我想最后一个条件(似乎是为了确保每个单词至少有一个音节)非常坏。它将在
made
中计算
e
,即使您试图用早期条件忽略它。一点提示-在循环开始时,do
char curr=tolower(str[i][q])
为避免重复检查所有条件,您需要重构代码,以避免在一个地方出现过多逻辑。我建议对单词行进行分析(以空格分隔的标记),然后分析音节的单词,在音节上应用这些规则。谢谢你的回答,我对状态机一无所知,所以如果可以的话,我有几个问题。我真的不明白for循环中发生了什么,你能不能再解释一下?你问的是for循环的哪个具体部分关于?该循环包含了我提供的几乎全部代码。我编写了一个工作版本,然后删除了更新状态变量的部分,以便您可以通过计算来学习。现在您需要解决的几乎全部问题都与以适当的方式设置或清除这些状态变量有关。每个变量都有一个meaning.如果你有一个关于你不理解的东西的更具体的问题,那就发问吧。对不起,我指的是for循环,比如for(char*p=str[I],等等)我真的不明白end在做什么以及为什么它是你的条件。我在最后一段中明确提到了它。它在循环中包含字符串的null终止符。另一种方法是使用do while循环,避免使用
strlen
。例如:
char*p=str[I];do{…}while(*p++!='\0');