向量数组的均值和众数 - 如何对函数进行较小的改进

Mean and Mode of vector array - How can I make a smaller improvement in the function

练习查找用户输入的数字列表中的 meanmode。我已经编写了程序并且它可以运行,但我想知道我的函数 'calcMode' 是否对于这个程序来说太大了。我刚刚开始研究功能,这是第一次尝试。编写更小的函数会更好吗?如果可以,我可以拆分哪些部分?我是 C++ 的新手,也在寻找我是否可以改进这段代码。是否可以进行任何更改以提高 运行 的效率?

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int calcMean(vector<int> numberList) 
{

    int originNumber = numberList[0];
    int nextNumber;
    int count = 0;
    int highestCount = 0;
    int mean = 0;

    for (unsigned int i = 0; i <= numberList.size() - 1; i++) 
    {
            nextNumber = numberList[i];
            if (nextNumber == originNumber) 
                count++;
            else 
            {
                cout << "The Number " << originNumber << " appears " << count << " times." << endl;
                count = 1;
                originNumber = nextNumber;
            }
        }

    if (count > highestCount)
    {
        highestCount = count;
        mean = originNumber;
    }
    cout << "The Number " << originNumber << " appears " << count << " times." << endl;     
    return mean;
}

int main() 
{
    vector<int> v;
    int userNumber;
    cout << "Please type a list of numbers so we can arrange them and find the mean: "<<endl;

    while (cin >> userNumber)  v.push_back(userNumber);

    sort(v.begin(), v.end());

    for (int x : v)    cout << x << " | ";

    cout << endl;
    cout<<calcMean(v)<<" is the mean"<<endl;
    return 0;
}

我个人不会将这段代码拆分成更小的块,除非我想在其他方法中重用一些代码。但就此方法而言,它更具可读性。

计算的执行顺序大约是 O(n),如果你问我的话,这很好

需要注意的一件事是在不需要时复制向量。

函数签名

int calcMode(vector<int> numberList)

表示 numberList 将被复制。

int calcMode(const & vector<int> numberList)

将避免复制。 Scott Meyer 的 Effective C++ 对此进行了讨论。

顺便说一句,调用是 numberList 是一种误导——它不是 list

在for循环中有几点值得注意:

for (unsigned int i = 0; i <= numberList.size()-1; i++)

首先,这可能每次都会计算size()。优化器可能会为您消除这一点,但有些人会写

for (unsigned int i = 0, size=numberList.size(); i <= size-1; i++)

size 以这种方式被找到一次,而不是每次都可能被找到。 他们甚至可能将 i++ 更改为 ++i。这里曾经有一个潜在的开销,因为 post-增量可能涉及额外的 temporary value

一个问题 - 你*确定这给出了正确的答案吗? 比较 nextNumber == originNumber 正在查看开头的第一个数字。 试试 1, 2, 2.

最后一点。如果这是通用的,如果列表为空会怎样?

Would it be better to write smaller functions?

  • 是的,您可以使用 std::map<>; 来完成同样的工作,这可能是 一种非常合适的方法来计算数组元素的重复。
  • 其次,知道它的大小是多少会更安全 大批。因此我建议如下:

std::cout << "Enter the size of the array: " << std::endl; std::cin >> arraySize;

  • calcMode()中,可以方便的const引用,这样数组 不会被复制到函数中。

以上是更新后的代码,您可以参考:

#include <iostream>
#include <algorithm>
#include <map>

int calcMode(const std::map<int,int>& Map)
{
    int currentRepetition = 0;
    int mode = 0;

    for(const auto& number: Map)
    {
        std::cout << "The Number " << number.first << " appears " << number.second << " times." << std::endl;

        if(currentRepetition < number.second )
        {
            mode = number.first;  // the number
            currentRepetition = number.second; // the repetition of the that number
        }
    }
    return mode;
}

int main()
{
    int arraySize;
    int userNumber;
    std::map<int,int> Map;

    std::cout << "Enter the size of the array: " << std::endl;
    std::cin >> arraySize;

    std::cout << "Please type a list of numbers so we can arrange them and find the mean: " << std::endl;
    while (arraySize--)
    {
        std::cin >> userNumber;
        Map[userNumber]++;
    }

    std::cout << calcMode(Map)<<" is the mode" << std::endl;
    return 0;
}

更新: 发布此答案后,我发现您使用 mean 而不是 mode 编辑了函数。我真的没听懂。

关于均值和众数:我建议您阅读更多。因为一般情况下,一个数据集可以有多个众数,而只有一个均值。