C++分词统计函数getTokenFreqVec返回token数量超预期 如何调整代码
问题根因
- 你采用
getline(isStream, value, ' ')按单个空格切割字符串,遇到连续空格、首尾空格时会切割出空字符串,代码没有过滤空字符串直接统计,导致多计数了不存在的空token:- 全空白输入时会切割出1个空串,所以返回token数为1,不符合预期的0
- 含连续空格的输入会切割出空串作为额外token,所以第二个测试本来只有2种token,多了1个空token变成3种
- 新增token时未给freq赋值为1,属于隐藏bug,会导致后续频次统计错误。
修改方案
- 替换分词逻辑:将
while (getline(isStream, value, ' '))替换为while (isStream >> value),istream的>>运算符默认会自动跳过所有连续空白字符,不会读出空字符串,从根源避免空token问题。如果需要保留getline的实现方式,可在transform执行后加判断:if (value.empty()) continue;跳过空串。
- 替换分词逻辑:将
- 新增TokenFreq时初始化频次:push_back前给
t.freq = 1;赋值,保证新token的初始频次正确。
- 新增TokenFreq时初始化频次:push_back前给
- 优化遍历逻辑:匹配到已有token后加break跳出循环,避免无效遍历。
修改后完整代码
void getTokenFreqVec(const string &istr, vector<NS_TOKEN_FREQ::TokenFreq> &tfVec) { string value; istringstream isStream(istr); // 使用>>运算符自动跳过空白,不会读出空串 while (isStream >> value) { transform(value.begin(), value.end(), value.begin(), ::tolower); bool exists = false; for (size_t i = 0; i < tfVec.size(); i++) { if (tfVec[i].token == value) { tfVec[i].freq += 1; exists = true; break; // 匹配到就跳出,不用继续遍历 } } if (!exists) { NS_TOKEN_FREQ::TokenFreq t; t.token = value; t.freq = 1; // 初始化新token的频次为1 tfVec.push_back(t); } } }
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

