每日一题(2022-01-27):句子中的有效单词数

每日一题(2022-01-27):句子中的有效单词数

来源:力扣
难度:中等
题目:2047. 句子中的有效单词数

题目详情

原题截图.png

题解思路

被标题和简单难度骗进来了,仔细一读发现事情并不简单,第一反应也是正则,看过评论区发现正则效率并不高,但是手写状态机又不是简单题目应该有的解法,想来想去感觉就用最常规的解法,逐字符扫描判断就ok了,先借助stringstream将字符按空格分割开会比较简单;
特别需要注意的一点是,本题由于描述规则不完善,导致存在一个反常理的现象:前后字符均为空格的标点符号也是有效的单词,即,本身也是一个单词,这个是不需要特殊考虑排除在外的。

代码结果

class Solution {
public:
    int countValidWords(string sentence) {
        // 有效单词总数
        int iCountValidWord = 0;
        // 借助 stringstream 按空格分割字符串
        vector<string> vecWords;
        string strTmp;
        stringstream ssInput(sentence);
        while (ssInput >> strTmp)
            vecWords.push_back(strTmp);
        for (const string& strWord : vecWords)
        {
            int iIdxStrWord = 0;
            int iSzStrWord = strWord.size();
            // 字符串是否有效
            bool bIsValid = true;
            // 是否已经存在连字符
            bool bHasHyphen = false;
            while (iIdxStrWord < iSzStrWord)
            {
                char cCurrLetter = strWord[iIdxStrWord];
                // 如果当前字符为数字则直接判定为非有效单词
                if (cCurrLetter >= '0' && cCurrLetter <= '9')
                {
                    bIsValid = false;
                    break;
                }
                if (cCurrLetter == '-')
                {
                    // 如果已存在连字符,或者连字符位于单词首尾位置,或者连字符前后不存在小写字母,则为非有效单词
                    if (bHasHyphen || iIdxStrWord == 0 || iIdxStrWord == iSzStrWord - 1 
                        || !islower(strWord[iIdxStrWord - 1]) || !islower(strWord[iIdxStrWord + 1]))
                    {
                        bIsValid = false;
                        break;
                    }
                    bHasHyphen = true;
                }
                // 如果标点符号不位于单词末尾,则为非有效单词
                if ((cCurrLetter == '!' || cCurrLetter == '.' || cCurrLetter == ',') 
                    && iIdxStrWord != iSzStrWord - 1)
                {
                    bIsValid = false;
                    break;
                }
                ++iIdxStrWord;
            }
            if (bIsValid) ++iCountValidWord;
        }
        return iCountValidWord;  
    }
};

运行结果.png