我正在阅读Accelerated C ++。目前我已经到了第3章的末尾,这是我正在努力做的练习:
“编写程序来计算和打印一组整数的四分位数。”
我找到了第一个和第二个四分位数,但我不知道如何找到第三个四分位数。这是我的代码:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main(){
cout<<"Enter numbers:";
int x;
vector<int>integers;
while(cin>>x)
integers.push_back(x);
typedef vector<int>::size_type vec_sz;
vec_sz size = integers.size();
sort(integers.begin(), integers.end());
vec_sz mid = size/2;
vec_sz q1 = mid/2;
double median;
median = size % 2 == 0 ? ((double)integers[mid] + (double)integers[mid-1]) / 2
: integers[mid];
double quartOne = ((double)integers[q1] + (double)integers[q1-1])/2;
cout<<"The First Quartile is: "<<quartOne<<endl;
cout<<"The Second Quartile is: "<<median<<endl;
return 0;
}
答案 0 :(得分:3)
一种方法是对集合进行排序,然后采用3个划分项:
vector<int> v = ...;
sort(v.begin(), v.end());
int q12 = v[v.size()*1/4];
int q23 = v[v.size()*2/4];
int q34 = v[v.size()*3/4];
这是数据项数量的O(nlogn)。
另一种方法是分别对三个部门的数据进行二进制搜索。即建议初始q12,通过传递数据来检查它是否正确,如果不正确则将其向上或向下调整一半,然后重复。同样适用于q23和q34。
这在技术上是O(n),因为32位int具有固定范围,并且可以在最多32次传递中进行二进制搜索。
答案 1 :(得分:2)
此解决方案实现了维基百科中用于计算quartiles的第二种方法。它为具有奇数和偶数长度的向量提供正确的值。
#include <vector>
#include <tuple>
#include <iostream>
using namespace std;
double median(vector<double>::const_iterator begin,
vector<double>::const_iterator end) {
int len = end - begin;
auto it = begin + len / 2;
double m = *it;
if ((len % 2) == 0) m = (m + *(--it)) / 2;
return m;
}
tuple<double, double, double> quartiles(const vector<double>& v) {
auto it_second_half = v.cbegin() + v.size() / 2;
auto it_first_half = it_second_half;
if ((v.size() % 2) == 0) --it_first_half;
double q1 = median(v.begin(), it_first_half);
double q2 = median(v.begin(), v.end());
double q3 = median(it_second_half, v.end());
return make_tuple(q1, q2, q3);
}
int main() {
vector<double> v = {2, 2, 3, 4, 4, 5, 5, 10};
auto q = quartiles(v);
cout << get<0>(q) << "," << get<1>(q) << "," << get<2>(q) << endl;
return 0;
}
它是为实数设计的,但它很容易适应整数值(只是将值四舍五入到它们最接近的整数)。