如果一个单词在一个字符串中重复了很多次,我该如何计算这个单词的重复次数和它们的位置呢?
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
getline(cin, str);
string str2;
getline(cin, str2);
const char* p = strstr(str.c_str(), str2.c_str());
if (p)
cout << "'" << str2 << "' find in " << p - str.c_str();
else
cout << target << "not find \"" << str << "\"";
return 0;
}
下面的代码使用了很多标准库来为我们做一些常见的事情。我使用一个文件将单词收集到一个大字符串中。然后,我使用std::StringStream
分隔空格上的单词,并将单个单词存储在std::Vector
(一个数组,可管理其大小,并在需要时增长)中。为了获得良好的单词计数,还必须删除标点符号和大写,这是在sanitize_word()
函数中完成的。最后,我将单词添加到一个映射中,其中单词是关键字,int
是该单词出现的次数。最后,我打印地图以获得完整的字数。
我直接进行任何字符串解析的唯一地方是在sanitize函数中,它是使用恰当命名的erase/remove习惯用法完成的。在可能的情况下让标准库为我们做这些工作要简单得多。
input.txt的内容:
I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. And when it has gone past, I will turn the inner eye to see its path. Where the fear has gone, there will be nothing. Only I will remain.
#include <algorithm>
#include <cctype>
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
// Removes puncuation marks and converts words to all lowercase
std::string sanitize_word(std::string word) {
word.erase(std::remove_if(word.begin(), word.end(),
[punc = std::string(".,?!")](auto c) {
return punc.find(c) != std::string::npos;
}),
word.end());
for (auto& c : word) {
c = std::tolower(c);
}
return word;
}
int main() {
// Set up
std::ifstream fin("input.txt");
if (!fin) {
std::cerr << "Error opening file...\n";
return 1;
}
std::string phrases;
for (std::string tmp; std::getline(fin, tmp);) {
phrases += tmp;
}
fin.close();
// Words are collected, now the part we care about
std::stringstream strin(phrases);
std::vector<std::string> words;
for (std::string tmp; strin >> tmp;) {
words.push_back(tmp);
}
for (auto& i : words) {
i = sanitize_word(i);
}
// std::map's operator[]() function will create a new element in the map if it
// doesn't already exist
std::map<std::string, int> wordCounts;
for (auto i : words) {
++wordCounts[i];
}
for (auto i : wordCounts) {
std::cout << i.first << ": " << i.second << '\n';
}
}
输出:
and: 2
be: 1
brings: 1
eye: 1
face: 1
fear: 5
gone: 2
has: 2
i: 5
inner: 1
is: 2
it: 2
its: 1
little-death: 1
me: 2
mind-killer: 1
must: 1
my: 1
not: 1
nothing: 1
obliteration: 1
only: 1
over: 1
pass: 1
past: 1
path: 1
permit: 1
remain: 1
see: 1
that: 1
the: 4
there: 1
through: 1
to: 2
total: 1
turn: 1
when: 1
where: 1
will: 5