【问题标题】:Can't display the correct frequency of integers in an array无法显示数组中整数的正确频率
【发布时间】:2020-09-11 14:37:20
【问题描述】:

我刚开始接触 C++。提示是“显示给定数组中整数的频率

以下是我写的代码:

#include <iostream>
#include <array>
using namespace std;

int main()
{
array <unsigned int,20> n = {1, 2, 5, 4, 3, 5, 2, 1, 3, 1, 4, 3, 3, 3, 2, 3, 3, 2, 2};

for(size_t i = 0; i < n[i]; i++)
 {
    int count = 0;
    for(size_t j = 0; j < n.size(); j++)
    {
        if (n[i] == n[j])
        {
             count++; 
        }
    }
    cout<<"Frequency of "<<n[i]<<" is "<<count<<endl;
 }
return 0;
}

但我的输出是:

1 的频率是 3
2 的频率是 5
5 的频率是 2
4的频率是2

为什么 3 的频率没有出现?我很确定这是一个愚蠢的错误,但我无法指出在哪里。

【问题讨论】:

  • i &lt; n[i] 的目的是什么?此外,使用std::map 更容易解决此问题。
  • @cigien 是的,好的。这并没有真正达到目的。我该怎么办?还有,我还没学过地图。
  • 请注意,在更正上述错误后,您将多次显示相同的信息。使用std::map 将简化这里的一切。排序也是一种选择。
  • @VasudhaJhingan 一种简单的可能性是首先扫描数组的最低和最高值,然后将它们用于主循环。

标签: c++ arrays for-loop


【解决方案1】:

这是一种计算值频率的简单方法:

std::map<int, int> freq;

for (int const i : n)
  freq[i]++;    // map has the nice property that it 
                // defaults the value of a key to 0

for (auto const &[i, count] : freq)  // this loop needs c++17
  std::cout << "Frequency of " << i << " is " << count << std::endl;

【讨论】:

  • @VasudhaJhingan 没问题 :) 如果它解决了您的问题,请考虑接受答案。
  • 适用于真正的代码(尽管添加了一些 const,该死的!:P) - 但没有直接回答有关 this 代码问题的问题,并且可能高级 C++ 入门课程(取决于它的结构)。不教算法,只教良好的 C++ 库用法。
  • @AsteroidsWithWings 是的,但是我认为 OPs 代码很糟糕,似乎没有一个明确的算法正在实施。但是我应该在哪里添加const?你是说第一个循环吗?这只是一个int
  • 这是一个 int 你没有改变 ;)
  • 我有一种感觉可能是这种情况:P
【解决方案2】:

因为:

for(size_t i = 0; i < n[i]; i++)
//                    ^^^^

……错了。

你应该去n.size()

目前,您只会上升到 4n[4]3,而 4 &lt; 3 不成立)。

这是为 j 上的循环正确完成的。

【讨论】:

    【解决方案3】:

    正如其他人指出的那样,有更好的方法可以做到这一点。 比如散列

    你可以在这里阅读关于这些:https://www.geeksforgeeks.org/counting-frequencies-of-array-elements/

    现在我要指出你哪里出错了。

    在第一个 for 循环中,将 i &lt; n[i] 替换为 i&lt;n.size()

    错误:

    for(size_t i = 0; i < n[i]; i++)
    

    正确:

    for (size_t i = 0; i < n.size(); i++)
    

    您的代码失败,因为 i=3 的值 n[i]=3 违反了您的 for 循环条件

    这里的代码将针对数字的所有重复运行,因此它将多次打印相同的结果,并且还将执行所有计算,因此请保持 一个访问过的数组,存储你已经计算过的数字。

    这是您的代码,但已更正

    #include <iostream>
    #include <array>
    #include <vector>
    using namespace std;
    
    int main()
    {
        array<unsigned int, 20> n = {1, 2, 5, 4, 3, 5, 2, 1, 3, 1, 4, 3, 3, 3, 2, 3, 3, 2, 2};
        vector<bool> visited(n.size(), false);
    
        for (size_t i = 0; i < n.size(); i++)
        {
            int count = 0;
            // Skip this element if already processed
            if (visited[i] == true) continue;
    
            for (size_t j = 0; j < n.size(); j++){ 
                if (n[i] == n[j]){ 
                    count++;
                    // marking indexes already visited
                    visited[j] = true;
                }
            }
            cout << "Frequency of " << n[i] << " is " << count << endl;
        }
        return 0;
    }
    

    但最好的选择是学习地图,它们非常有用且非常易于实施。

    https://www.geeksforgeeks.org/map-associative-containers-the-c-standard-template-library-stl/

    【讨论】:

    • n.size(),而不是n.size()-1
    • 哦,我通常在循环中添加相等我的错误我会纠正它谢谢...
    【解决方案4】:

    当您使用 std::array 时,我假设您熟悉 STL 那么为什么不使用它的力量来解决问题。

    首先从您的数组中找到唯一的元素。

    std::unordered_set<int> s(n.begin(), n.end());
    

    而不是简单地使用count 来计算数组中每个元素的数量。

    #include <algorithm>
    #include <array>
    #include <iostream>
    #include <unordered_set>
    int main()
    {
        std::array<unsigned int, 20> n = { 1, 2, 5, 4, 3, 5, 2, 1, 3, 1, 4, 3, 3, 3, 2, 3, 3, 2, 2 };
        std::unordered_set<int> s(n.begin(), n.end());
    
        for (const auto& itr : s) {
            std::cout << "Count of "<< itr << " Is equal to = " <<std::count(n.begin(), n.end(), itr) << std::endl;
        }
    }
    

    【讨论】:

    • 给投反对票的人!伴侣至少解释​​一下为什么?
    • 投了反对票,因为这个解决方案虽然看起来更好并且更不容易出错,但本质上与使用不合适(在某种意义上)STL 构造的 OP 的有缺陷的低效方法相同。如果我们使用 unordered_set,为什么不从 multiset 开始呢? en.cppreference.com/w/cpp/container/unordered_multiset/count 无论如何,如果在答案中添加了关于潜在效率低下的警告,我将收回我的反对票。
    • 我看到的唯一无效的事情是在 for 循环中使用了引用变量。如果还有什么其他的,请参考学习资料,对你很友好。
    • 对于初学者,您的解决方案遍历所有数组以构造无序集,然后对于集合中的每个元素,您再次遍历所有数组。对于 1..N 的序列,它将以 ~N^2 步运行。
    猜你喜欢
    • 2023-04-01
    • 2016-07-07
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 2015-03-02
    • 2013-08-16
    相关资源
    最近更新 更多