计算给定数字列表的四分位数
Compute the quartiles of a given list of numbers
我正在尝试完成 "Accelerated C++" 练习 3-2。我测试过,下四分位数和中位数计算正确,但上四分位数不正确。
例如,假设输入“50、60、70、80、90、100”,它会输出四分位数为60、75、80。
我有两个问题想解决:
1) 在这种情况下,上四分位数应为 90。
2) 如何让我的程序显示我的数字的浮点数或双精度版本?较低的四分位数更精确的是 62.5,而不是 60。
/* Write a program to compute and print the quartiles(quarter of the
* numbers with the largest values) of a set of integers
* The first quartile (Q1) is defined as the middle number between the smallest number and the median of the data set.
* The second quartile (Q2) is the median of the data.
* The third quartile (Q3) is the middle value between the median and the highest value of the data set.*/
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::endl;
using std::cout;
using std::cin;
int main() {
double x = 0;
double median, lowerQt, upperQt;
median = lowerQt = upperQt = 0;
vector<double> set;
typedef vector<double>::size_type vec_sz;
cout << "Enter integers followed by EOF: ";
while(cin >> x)
set.push_back(x);
vec_sz size = set.size();
if(size == 0) {
cout << "invalid" << endl;
return 1;
}
vec_sz mid = size / 2;
vec_sz lower = mid / 2;
vec_sz upper = size - mid;
sort(set.begin(), set.end());
median = size % 2 == 0 ? (set[mid] + set[mid - 1]) / 2 : set[mid];
lowerQt = mid % 2 == 0 ? (set[lower] + set[lower - 1]) / 2 : set[lower];
upperQt = mid % 2 == 0 ? (set[upper] + set[upper - 1]) / 2 : set[upper];
cout << lowerQt << endl << median << endl << upperQt;
}
对于初学者来说,您的代码有点混乱且难以阅读。如果你使用现代 C++ 编译器,你不需要那个愚蠢的 typedef。您可以使用类型推导:
auto size = set.size();
将 size % 2 == 0
用作布尔值是一个大问题,它通常写成 (size % 2)
为了清楚起见,只使用该表达式一次
确定四分位数的方法有三种,它们给出的答案不同,您的代码不匹配其中两种(因为每种方法都会检查数据集中项目的实际计数)。编码它匹配“1 -Var Stats" 方法,由于错误 return 您需要的值。
使用中位数将有序数据集分成两半。
如果原始有序数据集中有奇数个数据点,不包括中位数(有序列表中的中心值)在任何一半。
如果原始有序数据集中有偶数个数据点,则将此数据集恰好分成两半。
下四分位值为下半部分数据的中位数。上四分位值为上半部分数据的中位数。
我想,你期待 Tukey 的铰链 (midhinge) 吗?
使用中位数将有序数据集分成两半。
- 如果原始有序数据集中有奇数个数据点,包括两半的中位数(有序列表中的中心值)。
- 如果原始有序数据集中有偶数个数据点,则将此数据集准确地分成两半。
下四分位值为下半部分数据的中位数。上四分位值为上半部分数据的中位数。
如果关于统计的书太远了,wiki 和应用数学 stackexchange 中描述了算法。
研究你的代码行为:你计算 "mid" 只是通过除以数组的大小,如果你取上限或下限 "middle" 值则不受控制。为什么?理论上,在计数不均匀的情况下,如果四舍五入,您总是会取较大的值,但实际上您只取较小的值,因为您使用整数值进行运算,除法的结果将被截断。对于 size = 11,您的 mid 将为 5。"upper" index 会怎样?
auto upper = size - mid; //? upper = 6 That's not right
应该是
auto upper = (size + mid)/2;
第一种方法的正确答案是:60 75 90
我正在尝试完成 "Accelerated C++" 练习 3-2。我测试过,下四分位数和中位数计算正确,但上四分位数不正确。
例如,假设输入“50、60、70、80、90、100”,它会输出四分位数为60、75、80。
我有两个问题想解决:
1) 在这种情况下,上四分位数应为 90。 2) 如何让我的程序显示我的数字的浮点数或双精度版本?较低的四分位数更精确的是 62.5,而不是 60。
/* Write a program to compute and print the quartiles(quarter of the
* numbers with the largest values) of a set of integers
* The first quartile (Q1) is defined as the middle number between the smallest number and the median of the data set.
* The second quartile (Q2) is the median of the data.
* The third quartile (Q3) is the middle value between the median and the highest value of the data set.*/
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::endl;
using std::cout;
using std::cin;
int main() {
double x = 0;
double median, lowerQt, upperQt;
median = lowerQt = upperQt = 0;
vector<double> set;
typedef vector<double>::size_type vec_sz;
cout << "Enter integers followed by EOF: ";
while(cin >> x)
set.push_back(x);
vec_sz size = set.size();
if(size == 0) {
cout << "invalid" << endl;
return 1;
}
vec_sz mid = size / 2;
vec_sz lower = mid / 2;
vec_sz upper = size - mid;
sort(set.begin(), set.end());
median = size % 2 == 0 ? (set[mid] + set[mid - 1]) / 2 : set[mid];
lowerQt = mid % 2 == 0 ? (set[lower] + set[lower - 1]) / 2 : set[lower];
upperQt = mid % 2 == 0 ? (set[upper] + set[upper - 1]) / 2 : set[upper];
cout << lowerQt << endl << median << endl << upperQt;
}
对于初学者来说,您的代码有点混乱且难以阅读。如果你使用现代 C++ 编译器,你不需要那个愚蠢的 typedef。您可以使用类型推导:
auto size = set.size();
将 size % 2 == 0
用作布尔值是一个大问题,它通常写成 (size % 2)
为了清楚起见,只使用该表达式一次
确定四分位数的方法有三种,它们给出的答案不同,您的代码不匹配其中两种(因为每种方法都会检查数据集中项目的实际计数)。编码它匹配“1 -Var Stats" 方法,由于错误 return 您需要的值。
使用中位数将有序数据集分成两半。
如果原始有序数据集中有奇数个数据点,不包括中位数(有序列表中的中心值)在任何一半。
如果原始有序数据集中有偶数个数据点,则将此数据集恰好分成两半。
下四分位值为下半部分数据的中位数。上四分位值为上半部分数据的中位数。
我想,你期待 Tukey 的铰链 (midhinge) 吗?
使用中位数将有序数据集分成两半。
- 如果原始有序数据集中有奇数个数据点,包括两半的中位数(有序列表中的中心值)。
- 如果原始有序数据集中有偶数个数据点,则将此数据集准确地分成两半。
下四分位值为下半部分数据的中位数。上四分位值为上半部分数据的中位数。
如果关于统计的书太远了,wiki 和应用数学 stackexchange 中描述了算法。
研究你的代码行为:你计算 "mid" 只是通过除以数组的大小,如果你取上限或下限 "middle" 值则不受控制。为什么?理论上,在计数不均匀的情况下,如果四舍五入,您总是会取较大的值,但实际上您只取较小的值,因为您使用整数值进行运算,除法的结果将被截断。对于 size = 11,您的 mid 将为 5。"upper" index 会怎样?
auto upper = size - mid; //? upper = 6 That's not right
应该是
auto upper = (size + mid)/2;
第一种方法的正确答案是:60 75 90