You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

代码问题求助:统计文本高频单词结果异常

高频单词统计问题的排查与解决建议

嘿,我看你在统计段落高频单词时遇到了小麻烦——要么输出'Monday'要么没结果,这大概率是几个常见的细节没处理好,我给你梳理下问题点和解决办法:

可能的问题根源

  • 大小写未统一:比如Mondaymonday会被当成两个不同的单词,如果文本里Monday出现次数刚好最多,就会优先输出它;反之如果高频单词被拆分成大小写不同的版本,计数分散后可能导致没有明显的高频词。
  • 标点符号未过滤:单词末尾的.,!等标点会让同一个单词被识别成不同条目(比如Monday.Monday),导致真实高频词的计数被拆分,反而让没带标点的Monday脱颖而出。
  • 统计逻辑初始化错误:如果你的代码里把高频单词的初始值硬设成了Monday,或者计数变量初始化有问题,就会默认输出它;如果所有单词计数相同,可能没处理这种边界情况导致无输出。
  • 段落划分逻辑错误:如果段落的分割判断(比如空行识别)有问题,可能统计的不是目标段落的单词,结果自然异常。

具体解决步骤

1. 统一单词大小写

把所有单词转换成小写(或大写)后再统计,避免大小写差异导致的计数分散。可以用C++标准库的std::transform配合tolower实现:

#include <algorithm>
#include <cctype>

std::string toLower(std::string word) {
    std::transform(word.begin(), word.end(), word.begin(), ::tolower);
    return word;
}

2. 过滤标点符号

处理每个单词时,去掉首尾的非字母字符,确保同一个单词的不同形式(带标点/不带标点)被归为一类:

std::string cleanWord(std::string word) {
    // 先转小写
    word = toLower(word);
    // 找到第一个字母的位置
    size_t start = word.find_first_of("abcdefghijklmnopqrstuvwxyz");
    // 找到最后一个字母的位置
    size_t end = word.find_last_of("abcdefghijklmnopqrstuvwxyz");
    if (start == std::string::npos || end == std::string::npos) {
        return ""; // 没有有效字母的单词直接丢弃
    }
    return word.substr(start, end - start + 1);
}

3. 修正统计逻辑的初始化

确保高频单词的初始值不是硬编码的Monday,而是从第一个有效单词开始:

std::map<std::string, int> wordCount;
// 先完成所有单词的计数统计...

std::string mostFreqWord;
int maxCount = 0;
for (const auto& pair : wordCount) {
    if (pair.second > maxCount) {
        maxCount = pair.second;
        mostFreqWord = pair.first;
    }
}
// 处理所有单词计数相同的情况
if (!wordCount.empty() && maxCount == 1) {
    mostFreqWord = wordCount.begin()->first; // 可以返回第一个单词,或者自定义提示
}

4. 验证段落划分逻辑

确认你识别段落的逻辑(比如空行作为分隔符)是正确的,比如读取文件时,只有遇到空行才结束当前段落的统计:

std::string paragraph;
std::string line;
std::ifstream inFile("your_file.txt");
while (std::getline(inFile, line)) {
    if (line.empty()) {
        // 处理当前段落的统计
        processParagraph(paragraph);
        paragraph.clear();
    } else {
        paragraph += line + " ";
    }
}
// 别忘了处理文件最后一个没有空行结尾的段落
if (!paragraph.empty()) {
    processParagraph(paragraph);
}

完整示例代码片段

把上面的逻辑整合起来,你的高频单词统计函数大概是这样的:

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <sstream>
#include <algorithm>
#include <cctype>

std::string cleanWord(std::string word) {
    std::transform(word.begin(), word.end(), word.begin(), ::tolower);
    size_t start = word.find_first_of("abcdefghijklmnopqrstuvwxyz");
    size_t end = word.find_last_of("abcdefghijklmnopqrstuvwxyz");
    if (start == std::string::npos || end == std::string::npos) {
        return "";
    }
    return word.substr(start, end - start + 1);
}

std::string findMostFrequentWord(const std::string& paragraph) {
    std::map<std::string, int> wordCount;
    std::istringstream iss(paragraph);
    std::string word;

    while (iss >> word) {
        std::string cleaned = cleanWord(word);
        if (!cleaned.empty()) {
            wordCount[cleaned]++;
        }
    }

    if (wordCount.empty()) {
        return "无有效单词";
    }

    std::string mostFreqWord;
    int maxCount = 0;
    for (const auto& pair : wordCount) {
        if (pair.second > maxCount) {
            maxCount = pair.second;
            mostFreqWord = pair.first;
        }
    }

    return mostFreqWord;
}

int main() {
    std::ifstream inFile("input.txt");
    if (!inFile.is_open()) {
        std::cerr << "无法打开输入文件!" << std::endl;
        return 1;
    }

    std::string paragraph;
    std::string line;
    while (std::getline(inFile, line)) {
        if (line.empty()) {
            std::string result = findMostFrequentWord(paragraph);
            std::cout << "段落高频单词:" << result << std::endl;
            // 这里可以写入输出文件,比如用ofstream
            std::ofstream outFile("output.txt", std::ios::app);
            if (outFile.is_open()) {
                outFile << "段落高频单词:" << result << std::endl;
                outFile.close();
            }
            paragraph.clear();
        } else {
            paragraph += line + " ";
        }
    }

    // 处理最后一个段落
    if (!paragraph.empty()) {
        std::string result = findMostFrequentWord(paragraph);
        std::cout << "段落高频单词:" << result << std::endl;
        std::ofstream outFile("output.txt", std::ios::app);
        if (outFile.is_open()) {
            outFile << "段落高频单词:" << result << std::endl;
            outFile.close();
        }
    }

    inFile.close();
    return 0;
}

你可以先检查自己的代码有没有忽略这些细节,替换对应的逻辑后应该就能解决问题啦!

内容的提问来源于stack exchange,提问作者KhaNguyen

火山引擎 最新活动