向量数组的均值和众数 - 如何对函数进行较小的改进
Mean and Mode of vector array - How can I make a smaller improvement in the function
练习查找用户输入的数字列表中的 mean
和 mode
。我已经编写了程序并且它可以运行,但我想知道我的函数 '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
编辑了函数。我真的没听懂。
关于均值和众数:我建议您阅读更多。因为一般情况下,一个数据集可以有多个众数,而只有一个均值。
练习查找用户输入的数字列表中的 mean
和 mode
。我已经编写了程序并且它可以运行,但我想知道我的函数 '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
编辑了函数。我真的没听懂。
关于均值和众数:我建议您阅读更多。因为一般情况下,一个数据集可以有多个众数,而只有一个均值。