需手动维护unordered_set查重+vector保序,用istringstream分割,tolower转key判重但存原词,ostringstream拼接防多余空格。

用 std::set 去重并保持输入顺序需要额外处理
直接用 std::set 或 std::unordered_set 只能去重,但会丢失原始单词顺序。C++ 标准库没有“有序去重容器”,所以得手动维护一个已见集合 + 一个结果容器。
常见错误是边遍历边插入 std::set,然后直接输出 set 内容——这得到的是字典序结果,不是原顺序。
- 先按空格切分字符串(注意处理连续空格、首尾空格)
- 用
std::unordered_set<:string></:string>快速查重(O(1) 平均) - 用
std::vector<:string></:string>记录首次出现的单词顺序 - 最后拼接成新字符串,注意单词间只保留单个空格
std::istringstream 是最稳妥的单词分割方式
别用 find_first_of(" ") + substr 手动切,容易漏掉多个空格或制表符。用 std::istringstream 自动跳过所有空白符,语义清晰且健壮。
示例关键片段:
立即学习“C++免费学习笔记(深入)”;
std::istringstream iss(input);
std::string word;
std::unordered_set<std::string> seen;
std::vector<std::string> unique_words;
while (iss >> word) {
if (seen.find(word) == seen.end()) {
seen.insert(word);
unique_words.push_back(word);
}
}
注意大小写敏感性:默认区分 "Hello" 和 "hello"
如果需求是忽略大小写去重,不能直接把单词转小写再塞进 set——因为最终要输出原样单词(比如第一次出现的是 "Apple",后续的 "apple" 应该被删,但结果里得保留 "Apple")。
- 查重时用
std::tolower逐字符转换做 key - 但只对 key 操作,
unique_words仍存原始word - 避免用
std::transform改原始字符串,否则丢失首字母大写等格式
性能与边界情况:空字符串、纯空格、单字符单词
std::istringstream 对纯空格输入会直接失败,while (iss >> word) 不会进入循环,结果为空 vector——这是正确行为,不用额外判空。
单字符单词(如 "a"、"9")完全合法,std::string 和 unordered_set 都支持,无需特殊处理。
真正容易错的是结尾多空格或中间连续多个空格:手动拼接结果时若用 += word + " " 会多出尾部空格,应改用条件拼接或最后 pop_back()。
最简做法是用 std::ostringstream 辅助拼接:
std::ostringstream out;
for (size_t i = 0; i < unique_words.size(); ++i) {
if (i > 0) out << " ";
out << unique_words[i];
}
return out.str();
重复单词去重本身不难,难在空格处理和大小写策略是否符合真实业务场景——这两个地方一松懈,测试用例当场报错。


















