0

出于某种原因,这段代码正在打印出我列表中的所有单词,而我希望它只打印出超过三个 z 的单词

我已经设法解决了代码,在其搜索其中包含“zz”的单词下方,例如嗡嗡声或暴风雪。我的主要目标是在整个单词中搜索三个 z 的单词,例如 zblizzard 之类的。

Word* Dictionary::findzs()
{
    int wordIndex = 0;
    cout << "List : " << endl;
    while (wordIndex < MAX_WORDS) {
        string word1 = myWords[wordIndex]->word;
        wordIndex++;
        if (word1.find("zz") != std::string::npos){
            cout << word1 << endl;
        }
    }
    return 0;
}

更新:

bool has_3_zs(const std::string& s)
{
    return std::count(std::begin(s), std::end(s), 'z') >= 3;
}

void Dictionary::has3zs()
{
    int wordIndex = 0;
    string word = myWords[wordIndex]->word;
    while (wordIndex < MAX_WORDS) {
        for (auto& s : { word })
        {
            if (has_3_zs(s))
            {
                std::cout << s << '\n';
            }
        }
    }
    }
4

3 回答 3

4

有几个问题:

  1. string::find_first_of()不是正确使用的功能。它在字符串中搜索与其参数中指定的任何字符匹配的第一个字符。换句话说,您的代码确实会查找单个字母z(因为这是唯一出现在 中的不同字母subString)。如果您希望连续z找到三个,请改用。如果您希望在字符串中的任意位置找到 3 ,请使用.string::find()zstd::count()

  2. 您没有正确检查返回值。您隐含地将返回值与零进行比较,而您需要与string::npos.

  3. wordIndex++错位了。

  4. return myWords[wordIndex]看起来像是越界访问,可能导致未定义的行为

于 2013-09-23T09:25:15.823 回答
3

我现在明白了。您想在'z'任何地方匹配至少包含 3 个字符的字符串。

使用std::count. 这个例子:

#include <algorithm> // std::count
#include <iostream>  // std::cout
#include <iterator>  // std::begin, std::end
#include <string>    // std::string

// This is the function you care about.
// It returns `true` if the string has at least 3 'z's.
bool has_3_zs (const std::string& s)
{
    return std::count(std::begin(s), std::end(s), 'z') >= 3;
}

// This is just a test case. Ignore the way I write my loop.
int main()
{
    for (auto& s : {"Hello", "zWorzldz", "Another", "zStzzring"} )
    {
        if (has_3_zs(s))
        {
            std::cout << s << '\n';
        }
    }
}

印刷:

zWorzldz
zStzzring

编辑

好的,我写了一个更像你的例子。我的循环的编写方式与您的大致相同(我认为这不是最好的,但我不想进一步混淆)。

// This is the function you care about.
// It returns `true` if the string has at least 3 'z's.
bool has_3_zs (const std::string& s)
{
    return std::count(std::begin(s), std::end(s), 'z') >= 3;
}

struct SomeTypeWithAWord
{
    std::string word; // The bit you care about

    // Allow me to easily make these for my example
    SomeTypeWithAWord(char const * c) : word(c) {}
};

// This will contain the words.
// Don't worry about how I fill it up,
// I've just written it the shortest way I know how.
std::vector<SomeTypeWithAWord> myWords
                                {"Hello", "zWorzldz", "Another", "zStzzring"};

// This is the function you are trying to write.
// It loops over `myWords` and prints any with 3 or more 'z's.
void findzs()
{
    std::cout << "List : \n";
    std::vector<SomeTypeWithAWord>::size_type wordIndex = 0;
    while (wordIndex < myWords.size()) // Loop over all the words
    {
        const std::string& testWord = myWords[wordIndex].word;
        if (has_3_zs(testWord)) // Test each individual word
        {
            std::cout << testWord << '\n'; // Print it
        }
        ++wordIndex;
    }
}

int main()
{
    findzs();
}
于 2013-09-23T10:30:33.213 回答
0

编辑-BoB TFish 更简单,因此解决方案更好。

您可以使用 find_first_of 3 次来查看您是否(至少)在整个单词中分布了 3 个 z。尝试这样的事情:

Word* Dictionary::findzs()
    {
        int wordIndex = 0;
        cout << "List : " << endl;
        size_t where;
        int i;
        string subString = "z"; // or "zZ" if you want uppercase as well
        while (wordIndex < MAX_WORDS) {
            string word1 = myWords[wordIndex]->word;
            where  = 0;
            for (i = 0 ; i < 3 ; i++)
            {
              where =  word1.find_first_of(substring, where);
              if (where == string::npos)
                   break;
              where++; // fix...
            }

            if (i == 3)
            {
                cout << word1 << endl;
            }

            wordIndex++;
        }
        //return myWords[wordIndex]; - this will try to return myWords[MAX_WORDS] which is probably outside array bounds
       return NULL; // or whatever else you see fit

    }
于 2013-09-23T10:35:42.403 回答