【问题标题】:how to display common character if the two letters is equal in vector如果两个字母在向量中相等,如何显示公共字符
【发布时间】:2021-11-22 15:43:55
【问题描述】:

例如,我有向量 {'a','a','b','b','c'} 并且我想获得最多的字母,即 a 和 b,但此代码输出为 a;

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int getMostFrequentElement(std::vector<char> &arr)
{
    if (arr.empty())
        return -1;

    std::sort(arr.begin(), arr.end());

    auto last_int = arr.front();
    auto most_freq_int = arr.front();
    int max_freq = 0, current_freq = 0;

    for (const auto &i : arr) {
        if (i == last_int)
            ++current_freq;
        else {
            if (current_freq > max_freq) {
                max_freq = current_freq;
                most_freq_int = last_int;
            }

            last_int = i;
            current_freq = 1;
        }
    }

    if (current_freq > max_freq) {
        max_freq = current_freq;
        most_freq_int = last_int;
    }

    return most_freq_int;
}

int main(){
    std::vector<char> arr = {'a','a','b','b','c'};

    char ret = getMostFrequentElement(arr);
  
    std::cout << "Most frequent element = " << ret;

    
}

我可以知道为什么我的输出变成 a 而不是 a 和 b 吗?

输入向量 arr{'a','a','b','b','c'} 预期输出是 a 和 b

但我的输出是一个

【问题讨论】:

  • Team up with this asker。你们有很多共同点,就连代码都一样。
  • TL;DR 版本:不能指望返回一个值的函数不经过修改就返回两个值。
  • “我可以知道为什么我的输出变成 a 而不是 a 和 b 吗?” 其他人写了这段代码吗?很难想象你写了这段代码,期望char ret 的值是"a and b"
  • 在家庭作业上作弊可能会让你通过课程,但你认为如果你试图找到一份工作,人们不会弄明白的。作弊不会教你编程。
  • 这段代码似乎是从here 中提取的,经过了一些改进以使用char 而不是int

标签: c++ algorithm vector frequency function-definition


【解决方案1】:

您的函数仅将第一个最常见的字符作为已排序向量中的整数返回。

对于初学者来说,功能的实​​现并不好。该函数不应对通过引用传递的向量进行排序。是向量的所有者在调用函数之前决定是否对向量进行排序。该函数不得修改传递给它的向量。

如果您希望该函数返回向量中所有最常见的字符,那么您需要从本质上更改该函数。

例如,函数可以如下面的演示程序所示。

#include <iostream>
#include <vector>
#include <map>
#include <iterator>
#include <algorithm>

std::vector<char> getMostFrequentElement( const std::vector<char> &v )
{
    std::vector<char> result;
    
    std::map<char, size_t> m;
    
    
    for ( const auto &c : v ) ++m[c];
    
    auto it = std::max_element( std::begin( m ), std::end( m ), 
                                []( const auto &p1, const auto &p2 )
                                {
                                    return p1.second < p2.second;
                                } );

    if ( it != std::end( m ) )
    {
        for ( const auto &p : m )
        {
            if ( p.second == it->second ) result.push_back( p.first );
        }
    }
    
    return result;
}

int main() 
{
    std::vector<char> v = { 'a', 'a', 'b', 'b', 'c' };
    
    auto result = getMostFrequentElement( v );
    
    for ( const auto &c : result ) std::cout << c << ' ';
    std::cout << '\n';
    
    return 0;
}

程序输出是

a b

【讨论】:

    【解决方案2】:

    弗拉德的回答很好,应该被接受。

    我想展示一个额外的、更“现代”的 C++ 解决方案。

    函数体相当紧凑,仅包含 3 行代码。它将计算所有出现的 char 并根据出现的降序对其进行排序。

    所以,这个函数的调用者可以显示所有类型的信息。在下面的示例中,我显示了所有最顶层的元素。

    但可能会显示所有其他类型的评估。

    请看:

    #include <iostream>
    #include <vector>
    #include <utility>
    #include <algorithm>
    #include <set>
    #include <iterator>
    #include <unordered_map>
    
    // Writing some aliases to prevent later typing work and make the code a little bit more readable. ---------------------
    using DataType = char;
    using CounterType = unsigned int;
    using Pair = std::pair<DataType, CounterType>;
    using Counter = std::unordered_map<DataType, CounterType>;
    using Data = std::vector<DataType>;
    struct Comp { bool operator ()(const Pair& p1, const Pair& p2) const { return (p1.second == p2.second) ? p1.first<p2.first : p1.second>p2.second; } };
    using CountedAndSorted = std::multiset<Pair, Comp>;
    // ----------------------------------------------------------------------------------------------------------------------
    
    
    CountedAndSorted getMostFrequentElement(Data& data) {
        
        // Count
        Counter counter{};
        for (const char c : data) counter[c]++;
        
        // Return counted and sorted result
        return {counter.begin(), counter.end()};
    }
    
    
    // ------------------------
    // Test/Driver code
    int main() {
        
        // Test Data
        Data d = { 'a', 'a', 'b', 'b', 'c' };
        
        // Calculate result
        auto result = getMostFrequentElement(d);
        
        // Show output
        for (const auto& [c, count] : result) if (count == result.begin()->second) std::cout << c << ' ';
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-24
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-05
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      相关资源
      最近更新 更多