[英]histogram program gives strange output C++
我一直在编写代码以生成水平直方图。 该程序将用户输入的任意范围的数字输入向量。 然后,它向用户询问他们希望直方图开始的最低值,以及他们希望每个bin的大小。 例如:
如果lowestValue = 1
且binSize = 20
并且向量用值{1, 2, 3, 20, 30, 40, 50}
binSize = 20
填充,则它将输出如下内容:
(bin) (bars) (num)(percent)
[ 1-21) #### 4 57%
[21-41) ## 2 28%
[41-61) ## 2 28%
这是大多数这样做的代码:
void printHistogram(int lowestValue, int binSize, vector<double> v)
{
int binFloor = lowestValue, binCeiling = 0;
int numBins = amountOfBins(binSize, (int)range(v));
for (int i = 0; i<=numBins; i++)
{
binCeiling = binFloor+binSize;
int amoInBin = amountInBin(v,binFloor, binSize);
double perInBin = percentInBin(v, amoInBin);
if (binFloor < 10)
{
cout << "[ " << binFloor << '-' << binCeiling << ") " << setw(20) << left << formatBars(perInBin) << ' ' << amoInBin << ' '<< setprecision(4) << perInBin << '%' << endl;
binFloor += binSize;
}
else
{
cout << '[' << binFloor << '-' << binCeiling << ") " << setw(20) << left << formatBars(perInBin) << ' ' << amoInBin << ' '<< setprecision(4) << perInBin << '%' << endl;
binFloor += binSize;
}
}
}
以及计算每个仓中有多少项的函数:
int amountInBin(vector<double> v, int lowestBinValue, int binSize)
{
int count = 0;
for (size_t i; i<v.size(); i++)
{
if (v[i] >= lowestBinValue && v[i] < (lowestBinValue+binSize))
count += 1;
}
return count;
}
现在我的问题是:
由于某种原因,它不在20-40之间计数。 至少从测试中可以看到。 这是运行的图像:
任何帮助表示赞赏。
我建议使用另一种方法。 进行两次通过,首先计算箱的数量,然后进行另一次将它们加起来,看起来很脆弱,并且容易出错。 看到您尝试找出此类错误并不奇怪。 我认为您的原始方法太复杂了。
俗话说:“您对管道的思考越多,堵塞下水道就越容易”。 找到最简单的方法来做某事,这将带来最少的惊喜和陷阱。
我认为对这些值进行单次传递,计算每个值属于哪个bin并计算每个bin看到的值数量会更简单。 让我们使用std::map
,以bin编号为键,该值为每个bin中的值数。
void printHistogram(int lowestValue, int binSize, const std::vector<double> &v)
{
std::map<int, size_t> histogram;
for (auto value:v)
{
int bin_number= value < lowestValue ? 0:(value-lowestValue)/binSize;
++histogram[bin_number];
}
就是这样。 histogram
现在是您的直方图。 histogram [0]现在是第一个bin中的值数[lowestValue, lowestValue+binSize)
,该值还包括所有小于lowestValue
值。 histogram [1]将是在下一个bin中找到的值的数量,依此类推。
现在,您只需要遍历histogram
,然后生成实际的直方图即可。
现在,这里最棘手的部分是histogram
将仅包含找到至少1个值的键。 如果没有值放入箱中,则映射将不包括箱号。 因此,如果第一个bin中没有值,直方图[0]甚至将不存在,则映射中的第一个值将是矢量中最低值的bin。
通过一点点额外的智能遍历地图,这并不是一个很难解决的问题:
int next_bin_number=0;
for (auto b=histogram.begin(); b != histogram.end(); b++)
{
while (next_bin_number < b->first)
{
// next_bin_number had 0 values. Print the histogram row
// for bin #next_bin_number, showing 0 values in it.
++next_bin_number;
}
int n_values=b->second;
// Bin #n_next_number, with n_values, print its histogram row
++next_bin_number;
}
循环中的代码不会初始化i
,因此结果充其量是不可预测的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.