![](/img/trans.png)
[英]Do a file containing words separated by newline and a vector of strings for those words in C++ have same size?
[英]Counting the appearance of words in a vector and listing those in a list, C++
我有一個包含單獨單詞的 cpp 向量,我需要計算一個單詞使用列表出現的次數。 我嘗試遍歷列表,但在比較兩個 STL 容器時失敗,無論以下單詞是否已經在我的列表中。 如果沒有,我想將該單詞添加到我的列表中,外觀為 1。我有一個結構可以計算單詞在文本中出現的次數。 以下代碼返回一個單詞和數字列表,但不是每個都在我的向量中,我不明白為什么。
struct counter{
string word;
int sum = 1;
counter(){};
counter(string word): word(word){};
};
list<counter> list_count(vector<string> &text){
list<counter> word_count;
list<counter>::iterator it = word_count.begin();
for(string t:text){
if(it != word_count.end()){
it -> sum++;
} else {
word_count.push_back(counter(t));
}
++it;
}
return word_count;
}
先感謝您。
您實際上根本沒有搜索std::list
。 在通過std::vector
的每次循環迭代中,您需要從前到后搜索整個std::list
,例如:
#include <string>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
struct counter {
string word;
int sum = 1;
counter(const string &word): word(word) {}
};
list<counter> list_count(const vector<string> &text) {
list<counter> word_count;
for(const string &t: text) {
// perform an actual search here!
list<counter>::iterator it = find_if(
word_count.begin(), word_count.end(),
[&](counter &c){ return (c.word == t); }
);
if (it != word_count.end()) {
it->sum++;
} else {
word_count.emplace_back(t);
}
}
return word_count;
}
話雖如此, std::list
對元素計數來說是一個糟糕的解決方案。 更好的解決方案是使用std::(unordered_)map
代替(除非您需要保留找到的單詞的順序,這兩個都不會這樣做),例如:
#include <string>
#include <map>
#include <vector>
using namespace std;
map<string, int> list_count(const vector<string> &text) {
map<string, int> word_count;
for(const string &t: text) {
word_count[t]++;
}
return word_count;
}
現場演示(使用std::map
)
現場演示(使用std::unordered_map
)
list<counter> list_count(const vector<string>& text) {
list<counter> word_count;
for (const string& t : text) {
auto it = std::find_if(word_count.begin(), word_count.end(),
[&](const counter& c){ return c.word == t; });
if (it != word_count.end()) {
it -> sum++;
} else {
word_count.push_back(counter(t));
}
}
return word_count;
}
未經測試的代碼。
您正在嘗試使用低效的方法。 標准 class 模板列表不能隨機訪問其元素。 每個新元素都附加到列表的末尾。 要查找一個元素是否已經存在於它的列表元素中,需要按順序遍歷。
使用標准容器std::map
會非常有效。 此外,在這個容器中,單詞將被排序。
例如,您可以聲明
std::map<std::string, size_t> counters;
不過,如果您想使用該列表,那么 function 可以如下面的演示程序所示。
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <iterator>
#include <algorithm>
struct counter
{
std::string word;
size_t n = 0;
counter() = default;
counter( const std::string &word ): word( word ), n( 1 ){}
};
std::list<counter> list_count( const std::vector<std::string> &text )
{
std::list<counter> word_count;
for ( const auto &s : text )
{
auto it = std::find_if( std::begin( word_count ), std::end( word_count ),
[&s]( const auto &c ) { return c.word == s; } );
if ( it == std::end( word_count ) )
{
word_count.push_back( s );
}
else
{
++it->n;
}
}
return word_count;
}
int main()
{
std::vector<std::string> v { "first", "second", "first" };
auto word_count = list_count( v );
for ( const auto &c : word_count )
{
std::cout << c.word << ": " << c.n << '\n';
}
return 0;
}
它的 output 是
first: 2
second: 1
注意結構計數器的定義是多余的。 您可以改用標准的 class std::pair。 給你。
#include <iostream>
#include <string>
#include <utility>
#include <list>
#include <vector>
#include <iterator>
#include <algorithm>
std::list<std::pair<std::string, size_t>> list_count( const std::vector<std::string> &text )
{
std::list<std::pair<std::string, size_t>> word_count;
for ( const auto &s : text )
{
auto it = std::find_if( std::begin( word_count ), std::end( word_count ),
[&s]( const auto &p ) { return p.first == s; } );
if ( it == std::end( word_count ) )
{
word_count.emplace_back( s, 1 );
}
else
{
++it->second;
}
}
return word_count;
}
int main()
{
std::vector<std::string> v { "first", "second", "first" };
auto word_count = list_count( v );
for ( const auto &p : word_count )
{
std::cout << p.first << ": " << p.second << '\n';
}
return 0;
}
如果使用std::map
那么 function 看起來很簡單。
#include <iostream>
#include <string>
#include <vector>
#include <map>
std::map<std::string, size_t> list_count( const std::vector<std::string> &text )
{
std::map<std::string, size_t> word_count;
for ( const auto &s : text )
{
++word_count[s];
}
return word_count;
}
int main()
{
std::vector<std::string> v { "first", "second", "first" };
auto word_count = list_count( v );
for ( const auto &p : word_count )
{
std::cout << p.first << ": " << p.second << '\n';
}
return 0;
}
只有在對字符串向量進行排序的情況下,使用列表才會有效。
這是一個演示程序。
#include <iostream>
#include <string>
#include <list>
#include <vector>
struct counter
{
std::string word;
size_t n = 0;
counter() = default;
counter( const std::string &word ): word( word ), n( 1 ){}
};
std::list<counter> list_count( const std::vector<std::string> &text )
{
std::list<counter> word_count;
for ( const auto &s : text )
{
if ( word_count.empty() || word_count.back().word != s )
{
word_count.push_back( s );
}
else
{
++word_count.back().n;
}
}
return word_count;
}
int main()
{
std::vector<std::string> v { "A", "B", "B", "C", "C", "C", "D", "D", "E" };
auto word_count = list_count( v );
for ( const auto &c : word_count )
{
std::cout << c.word << ": " << c.n << '\n';
}
return 0;
}
它的 output 是
A: 1
B: 2
C: 3
D: 2
E: 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.