计算两个字符序列

时间:2017-08-16 19:38:13

标签: c++

我也是C ++新手,但有其他语言经验。

我正在努力:

书籍: C ++ Primer 5th Ed。
练习: 5.12

在使用开关结构计算元音,空格和制表符的过程中,练习还要求跟踪两个字符序列ffflfi出现的次数。一些输入的文字。我已经看到了这个问题的其他解决方案,大多数使用布尔标志类型结构,但我选择使用字符串迭代器来跟踪。然而,对于C ++来说,我不确定我的代码是否存在任何固有的危险(即指向无效对象的迭代器)。这段代码看起来不错吗?

#include <iostream>
#include <string>

using std::string;

using std::cin;
using std::cout;
using std::endl;

int main()
{
    string text;
    unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, nlCnt = 0, tabCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0;
    bool flag = false;

    while (getline(cin, text))
        for (auto it = text.begin(); it != text.end(); ++it) {

            *it = tolower(*it);
            switch (*it) {

            case 'a' :
                ++aCnt;
                break;
            case 'e' :
                ++eCnt;
                break;
            case 'i': 
                if (it != text.begin())
                    if (*(it - 1) == 'f')
                        ++fiCnt;
                    else
                        ++iCnt;
                break;
            case 'o' : 
                ++oCnt;
                break;
            case 'u' : 
                ++uCnt;
                break;
            case ' ':
                ++spaceCnt;
                break;
            case '\n':
                ++nlCnt;
                break;
            case '\t':
                ++tabCnt;
                break;
            case 'f' :
                //Control strucutre that checks if the character pointed to previously was an f.
                if (it != text.begin())
                    if (*(it - 1) == 'f')
                        ++ffCnt;
                break;
            case 'l':
                if (it != text.begin())
                    if (*(it - 1) == 'f')
                        ++flCnt;
                break;
            }

        }

    cout << "The number of 'a' vowels is: \t" << aCnt << endl;
    cout << "The number of 'e' vowels is: \t" << eCnt << endl;
    cout << "The number of 'i' vowels is: \t" << iCnt << endl;
    cout << "The number of 'o' vowels is: \t" << oCnt << endl;
    cout << "The number of 'u' vowels is: \t" << uCnt << endl;
    cout << "The number of tabs read is: \t" << tabCnt << endl;
    cout << "The number of newlines is: \t" << nlCnt << endl;
    cout << "The number of spaces read is: \t" << spaceCnt << endl;
    cout << "The number of 'ff' read is: \t" << ffCnt << endl;
    cout << "The number of 'fl' read is: \t" << flCnt << endl;
    cout << "The number of 'fi' read is: \t" << fiCnt << endl;


    return 0;
}

2 个答案:

答案 0 :(得分:2)

*it = tolower(*it);正在修改字符串。我不认为这是你想做的事情,因为通常计数假定未经修改的传入序列。我建议你使用const_iterator来防止这些问题。

答案 1 :(得分:0)

如果您需要随意修改容器,多次访问元素或以非线性方式迭代容器,则应使用普通for循环或其中一个表兄弟

基于范围的for适用于需要访问容器的每个元素一次的情况。当您多次访问某些元素时可能会导致问题。

你应该使用const_iterator作为@SergeyA提到的。 并试图修改*it

switch (tolower(*it))

或将其存储到temp变量。

同样优秀的做法是为每mapchar或其他任何内容使用string个计数器。

std::map<char,unsigned> charCounter;
charCounter['a']++;

而不是10 printf()

for(auto const & c : charCounter)
{
    for(auto const & i : charCounter.second)
    {
        cout << "The number of " << c << " vowels is: \t" << i << endl;
    }
}