[英]If a word is repeated many times in a string, how can I count the number of repetitions of the word and their positions?
如果一個單詞在一個字符串中重復多次,我如何計算單詞的重復次數及其位置?
#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::string
中使用find()
。 find()
返回字符串中 substring 的第一個匹配項(如果沒有匹配項,則返回std::string::npos
),因此您需要循環直到find()
無法找到您的字符串的更多匹配項.
就像是:
#include <string>
#include <vector>
#include <cstdio>
int main(void) {
std::string largeString = "Some string with substrings";
std::string mySubString = "string";
int numSubStrings = 0;
std::vector<size_t> locations;
size_t found = 0;
while(true) {
found = largeString.find(mySubString, found+1);
if (found != std::string::npos) {
numSubStrings += 1;
locations.push_back(found);
}
else {
break; // there are no more matches
}
}
printf("There are %d occurences of: \n%s \nin \n%s\n", numSubStrings, mySubString.c_str(), largeString.c_str());
}
哪個輸出:
There are 2 occurences of:
string
in
Some string with substrings
下面的代碼使用了很多標准庫來為我們做一些常見的事情。 我使用一個文件將單詞收集到一個大字符串中。 然后,我使用std::stringstream
分隔空格上的單詞,並將各個單詞存儲在std::vector
(一個管理其大小並在需要時增長的數組)中。 為了獲得良好的單詞計數,還必須刪除標點符號和大寫字母,這是在sanitize_word()
function 中完成的。 最后,我將單詞添加到 map 中,其中單詞是鍵, int
是該單詞出現次數的計數。 最后,我打印 map 以獲得完整的字數。
我直接進行任何字符串解析的唯一地方是清理 function,它是使用恰當命名的擦除/刪除習語完成的。 在可能的情況下讓標准庫為我們完成工作要簡單得多。
在單詞被分離和清理后,定位單詞出現的位置也變得微不足道。
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';
}
// Now we'll do code to locate a certain word, "fear" for this example
std::string wordToFind("fear");
auto it = wordCounts.find(wordToFind);
std::cout << "\n\n" << it->first << ": " << it->second << '\n';
std::vector<int> locations;
for (std::size_t i = 0; i < words.size(); ++i) {
if (words[i] == wordToFind) {
locations.push_back(i);
}
}
std::cout << "Found at locations: ";
for (auto i : locations) {
std::cout << i << ' ';
}
std::cout << '\n';
}
Output:
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
fear: 5
Found at locations: 3 4 8 20 50
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.