Code:[ZachxPKU/AcceleratedCPlusPlus]
Accelerated C++
Chapter 3 Working with batches of data
本章介绍程序复杂性(Complexity)的来源之一——处理多条数据。
3.1 Computing student grades
两个缩写:
- ios: iostream size
- iomanip: iostream manipulate
由于endl过于常用,所以它在iostream头文件中。
关于end-of-file操作,在Clion中执行时貌似“Command+D”没有效果,在terminal中调用时,“Ctrl+D”可以操作成功。(平时成绩输完后,输入回车,然后“Ctrl+D”。这个问题不需要纠结!)
- default-initialization 默认初始化
- undefined 未定义
这里需要注意,对于内建的局部变量,如果在声明时没有赋值,那么它们会是未定义的。
另外,我们需要注意的是;
streamsize prec = cout.precision(3);
这里是吧cout的精度设为3,并且返回原来的精度,赋值给prec。
3.1.1 Testing for end of input
这一节主要就是在讲下面这句话:
while(cin >> x)
因为,我们之前讲过括号里面的表达式会返回一个istrem对象cin,cin不是bool类型,怎么能判断真假呢?
这里涉及C++内部的类型转换实现,这里会把cin转换成bool类型,转换的依据就是当次读取数据是否成功。本书的后面会再次讨论这个问题。
3.1.2 The loop invariant
这一部分的不变式讨论,我仍然暂时觉得没有什么意义。
3.2 Using medians instead of averages
3.2.1 Storing a collection of data in vector
- container 容器
- template classes 模板类
3.2.2 Generating the output
- typedef 定义别名
需要注意的是,定义出来的别名的有效范围和通常定义的局部变量一样。
sort(homework.begin(), homework.end());
需要注意的是,sort函数是原位排序,排序后的结果会覆盖原来的内存位置。
double median;
median = size % 2 == 0 ? (homework[mid] + homework[mid - 1]) / 2 : homework[mid]
这里出现求余符号"%"和条件运算符号“? : ”,其中条件运算符号的使用方法需要注意。另外需要注意的是偶数个数时,中位数的计算方法是“homework[mid] + homework[mid - 1]) / 2”。
3.2.3 Some additional observations
如果我们不检查homework.size()是否为0,而执行homework[0],则会出现难以预料(all bets are off)的值。
同时也需要注意,因为标准库里所有类型的size_type都是无符号整数,而当无符号整数和有符号整数运算时,有符号整数会转换为无符号整数,因此,
homework.size() - 100
上面这句只会得到一个无符号整数,值会大于等于0,而不会得到一个负数,即使第一项的值小于100。这是需要特别注意的!!!
通过C++标准认证的实现,数据结构和算法效率是有底线的,哈哈!
3.3 Details
Tips
Tip 3-1
四分位数的计算方法有很多,且结果不统一,下面的实现参考维基百科中的计算法一。
//
// Created by Zach on 2022/8/16.
//
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
cout << "Enter the set of integers, "
"followed by end-of-file: ";
double x;
vector<double> set_int;
while (cin >> x) {
set_int.push_back(x);
}
typedef vector<double>::size_type vec_sz;
vec_sz size = set_int.size();
if(size < 2) {
cout << endl << "You must enter the set of integers(At least two values). "
"Please try again." << endl;
return 1;
}
// sort the data
sort(set_int.begin(), set_int.end());
vec_sz mid = size / 2;
double upper_quartile;
double median;
double lower_quartile;
median = size % 2 == 0 ? (set_int[mid] + set_int[mid - 1]) / 2 : set_int[mid];
vec_sz half_size = mid;
vec_sz half_mid = half_size / 2;
lower_quartile = half_size % 2 == 0 ? (set_int[half_mid] + set_int[half_mid - 1]) / 2 : set_int[half_mid];
if(size % 2 == 0){
upper_quartile = half_size % 2 == 0 ? (set_int[half_size + half_mid] + set_int[half_size + half_mid - 1
]) /2 : set_int[half_size + half_mid];
} else{
upper_quartile = half_size % 2 == 0 ? (set_int[half_size + half_mid + 1] + set_int[half_size + half_mid])
/ 2 : set_int[half_size + half_mid + 1];
}
streamsize prec = cout.precision();
cout << "Lower quartile: " << setprecision(3)
<< lower_quartile << endl;
cout << "median quartile: " << setprecision(3)
<< median << endl;
cout << "Upper quartile: " << setprecision(3)
<< upper_quartile << endl;
cout << setprecision(prec);
return 0;
}