簡體   English   中英

計算向量中單詞的出現次數並列出列表中的單詞,C++

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM