2024年12月完成(补充提交)
This commit is contained in:
commit
4e2bf47db0
7
Chapter 0/0-2.cpp
Normal file
7
Chapter 0/0-2.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include<iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"This (\") is a quote , and this (\\) is a backlash."<<std::endl;
|
||||
return 0;
|
||||
}
|
15
Chapter 1/1-6.cpp
Normal file
15
Chapter 1/1-6.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"What is your name? ";
|
||||
std::string name;
|
||||
std::cin>>name;
|
||||
std::cout<<"Hello, "<<name
|
||||
<<std::endl<<"And what is yours? ";
|
||||
std::cin>>name;
|
||||
std::cout<<"Hello, "<<name
|
||||
<<"; nice to meet you too!"<<std::endl;
|
||||
return 0;
|
||||
}
|
50
Chapter 2/2-5.cpp
Normal file
50
Chapter 2/2-5.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include<iostream>
|
||||
int main()
|
||||
{
|
||||
std::cout << "输入正方形的边长:";
|
||||
float a, b, c, d;
|
||||
std::cin >> a;
|
||||
std::cout << "输入长方形的长和宽:";
|
||||
std::cin >> b >> c;
|
||||
std::cout << "输入三角形的高:";
|
||||
std::cin >> d;
|
||||
|
||||
std::cout << "正方形:" << std::endl;
|
||||
for (int i = 0; i < a; i++) {
|
||||
for (int j = 0; j < a; j++) {
|
||||
if (i == a - 1 || i == 0 || j == a - 1 || j == 0) {
|
||||
std::cout << "*";
|
||||
}
|
||||
else {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "长方形:" << std::endl;
|
||||
for (int i = 0; i < c; i++) {
|
||||
for (int j = 0; j < b; j++) {
|
||||
if (i == c - 1 || i == 0 || j == b - 1 || j == 0) {
|
||||
std::cout << "*";
|
||||
}
|
||||
else {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "三角形:" << std::endl;
|
||||
for (int i = 0; i < d; i++) {
|
||||
for (int j = 0; j <= i; j++) {
|
||||
if (j == 0 || j == i || i == 0 || i == d - 1) {
|
||||
std::cout << "*";
|
||||
}
|
||||
else {
|
||||
std::cout << " ";
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
13
Chapter 2/2-8.cpp
Normal file
13
Chapter 2/2-8.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include<iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "输入要计算的区间范围:";
|
||||
float a, b, c;
|
||||
c = 1;
|
||||
std::cin >> a >> b;
|
||||
for (float i = a; i < b; i++) {
|
||||
c = i * c;
|
||||
}
|
||||
std::cout << c;
|
||||
}
|
48
Chapter 3/3-3.cpp
Normal file
48
Chapter 3/3-3.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<map>
|
||||
int main()
|
||||
{
|
||||
std::cout << "请输入单词:" << std::endl;
|
||||
std::string word;
|
||||
std::map<std::string, int>word_data;
|
||||
while (std::cin >> word)
|
||||
word_data[word] = word_data[word] + 1;
|
||||
std::map<std::string, int>::iterator mp_next = word_data.begin();
|
||||
while (mp_next != word_data.end())
|
||||
{
|
||||
std::cout << mp_next->first << " 的出现次数:" << mp_next->second << std::endl;
|
||||
mp_next++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <string> // 引入字符串库
|
||||
#include <map> // 引入map容器库
|
||||
|
||||
int main()
|
||||
{
|
||||
// 输出提示信息
|
||||
std::cout << "请输入单词:" << std::endl;
|
||||
|
||||
std::string word; // 用于存储用户输入的单词
|
||||
std::map<std::string, int> word_data; // 定义一个map容器,key为单词,value为单词出现次数
|
||||
|
||||
// 循环读取用户输入的单词,直到输入结束(如按 Ctrl+D)
|
||||
while (std::cin >> word)
|
||||
word_data[word] = word_data[word] + 1; // 更新单词出现次数
|
||||
|
||||
// 定义一个迭代器,用于遍历map中的所有元素
|
||||
std::map<std::string, int>::iterator mp_next = word_data.begin();
|
||||
|
||||
// 遍历map并输出每个单词及其出现次数
|
||||
while (mp_next != word_data.end())
|
||||
{
|
||||
std::cout << mp_next->first << " 的出现次数:" << mp_next->second << std::endl;
|
||||
mp_next++; // 移动到下一个元素
|
||||
}
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
58
Chapter 4/4-5.cpp
Normal file
58
Chapter 4/4-5.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include<iostream>
|
||||
#include<string>
|
||||
#include<map>
|
||||
int main()
|
||||
{
|
||||
int a = 0;
|
||||
std::cout << "请输入单词:" << std::endl;
|
||||
std::cout << "退出按ctrl+z后回车" << std::endl;
|
||||
std::string word;
|
||||
std::map<std::string, int>word_data;
|
||||
while (std::cin >> word) {
|
||||
word_data[word] = word_data[word] + 1;
|
||||
a = a + 1;
|
||||
}
|
||||
std::map<std::string, int>::iterator mp_next = word_data.begin();
|
||||
std::cout << "输入的单词个数:" << a << std::endl;
|
||||
while (mp_next != word_data.end())
|
||||
{
|
||||
std::cout << mp_next->first << " 的出现次数:" << mp_next->second << std::endl;
|
||||
mp_next++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <string> // 引入字符串库
|
||||
#include <map> // 引入map容器库
|
||||
|
||||
int main()
|
||||
{
|
||||
int a = 0; // 用于统计输入的单词总数
|
||||
std::cout << "请输入单词:" << std::endl; // 提示用户输入单词
|
||||
std::cout << "退出按ctrl+z后回车" << std::endl; // 提示用户如何结束输入
|
||||
|
||||
std::string word; // 定义一个字符串变量,用于存储单个单词
|
||||
std::map<std::string, int> word_data; // 定义一个map容器,key为单词,value为单词出现的次数
|
||||
|
||||
// 循环读取用户输入的单词,直到用户输入结束(Ctrl+Z后回车)
|
||||
while (std::cin >> word) {
|
||||
word_data[word] = word_data[word] + 1; // 更新单词出现次数,若不存在则初始化为1
|
||||
a = a + 1; // 每读取一个单词,计数器加1
|
||||
}
|
||||
|
||||
// 定义一个迭代器,用于遍历map容器
|
||||
std::map<std::string, int>::iterator mp_next = word_data.begin();
|
||||
|
||||
// 输出总的输入单词数量
|
||||
std::cout << "输入的单词个数:" << a << std::endl;
|
||||
|
||||
// 遍历map容器,输出每个单词及其出现次数
|
||||
while (mp_next != word_data.end())
|
||||
{
|
||||
std::cout << mp_next->first << " 的出现次数:" << mp_next->second << std::endl; // 输出单词和对应次数
|
||||
mp_next++; // 移动迭代器到下一个元素
|
||||
}
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
55
Chapter 4/4-7.cpp
Normal file
55
Chapter 4/4-7.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include<iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
double a, b = 0, c = 0;
|
||||
std::cout << "请输入数据:" << std::endl << "退出按ctrl+z后回车" << std::endl;
|
||||
while (std::cin >> a) {
|
||||
b = b + a;
|
||||
c++;
|
||||
}
|
||||
b = b / c;
|
||||
std::cout << "平均数为:" << b << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
CSDN资料
|
||||
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
vector<double> nums;
|
||||
double num;
|
||||
|
||||
while (cin >> num)
|
||||
nums.push_back(num);
|
||||
|
||||
cout << accumulate(nums.begin(), nums.end(), 0.0) / nums.size() << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <numeric> // 引入numeric库,用于使用accumulate函数
|
||||
#include <vector> // 引入vector容器库
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
vector<double> nums; // 定义一个动态数组,用于存储用户输入的数值
|
||||
double num; // 用于接收用户输入的单个数值
|
||||
|
||||
// 循环读取用户输入的数值,直到输入结束(Ctrl+Z 或 Ctrl+D 后回车)
|
||||
while (cin >> num)
|
||||
nums.push_back(num); // 将输入的数值添加到vector中
|
||||
|
||||
// 使用accumulate计算vector中所有数值的总和,并除以数值个数以计算平均值
|
||||
// 初始值设为0.0,避免因类型推导导致整型初始值
|
||||
cout << accumulate(nums.begin(), nums.end(), 0.0) / nums.size() << endl;
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
88
Chapter 5/5-8例题改/5-8pics_main.cpp
Normal file
88
Chapter 5/5-8例题改/5-8pics_main.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pics.h"
|
||||
|
||||
using std::cout;
|
||||
using std::copy;
|
||||
using std::endl;
|
||||
using std::ostream_iterator;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<string> p;
|
||||
p.push_back("this is an");
|
||||
p.push_back("example");
|
||||
p.push_back("to");
|
||||
p.push_back("illustrate");
|
||||
p.push_back("framing");
|
||||
|
||||
ostream_iterator<string>ofile(cout, "\n");
|
||||
copy(p.begin(), p.end(), ofile);
|
||||
cout << endl;
|
||||
|
||||
vector<string> f = frame(p);
|
||||
copy(f.begin(), f.end(), ofile); cout << endl;
|
||||
|
||||
vector<string> h = hcat(p,frame(p));
|
||||
copy(h.begin(), h.end(), ofile);
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <algorithm> // 引入标准算法库(用于std::copy等算法)
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <iterator> // 引入迭代器库(用于std::ostream_iterator)
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组(vector)容器库
|
||||
|
||||
#include "pics.h" // 引入自定义头文件,提供frame和hcat函数的声明
|
||||
|
||||
using std::cout; // 引入标准输出对象
|
||||
using std::copy; // 引入标准拷贝算法
|
||||
using std::endl; // 引入标准换行符
|
||||
using std::ostream_iterator; // 引入输出流迭代器
|
||||
using std::string; // 引入标准字符串类
|
||||
using std::vector; // 引入标准向量类
|
||||
|
||||
int main()
|
||||
{
|
||||
// 定义一个存储字符串的vector,并向其中添加多行字符串
|
||||
vector<string> p;
|
||||
p.push_back("this is an"); // 添加字符串到vector
|
||||
p.push_back("example");
|
||||
p.push_back("to");
|
||||
p.push_back("illustrate");
|
||||
p.push_back("framing");
|
||||
|
||||
// 定义输出流迭代器,用于将vector内容输出到标准输出
|
||||
ostream_iterator<string> ofile(cout, "\n");
|
||||
|
||||
// 输出vector p的内容到终端
|
||||
copy(p.begin(), p.end(), ofile);
|
||||
cout << endl; // 输出一个空行分隔内容
|
||||
|
||||
// 调用frame函数为vector p添加边框,并返回新vector
|
||||
vector<string> f = frame(p);
|
||||
|
||||
// 输出带边框的vector内容
|
||||
copy(f.begin(), f.end(), ofile);
|
||||
cout << endl; // 输出一个空行分隔内容
|
||||
|
||||
// 调用hcat函数,将原始vector p与带边框的vector f水平连接
|
||||
vector<string> h = hcat(p, frame(p));
|
||||
|
||||
// 输出水平连接后的vector内容
|
||||
copy(h.begin(), h.end(), ofile);
|
||||
cout << endl; // 输出一个空行分隔内容
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
||||
|
108
Chapter 5/5-8例题改/pics.cpp
Normal file
108
Chapter 5/5-8例题改/pics.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pics.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::max;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//#include "../minmax.h"
|
||||
#else
|
||||
//using std::max;
|
||||
#endif
|
||||
|
||||
string::size_type width(const vector<string>& v)
|
||||
{
|
||||
string::size_type maxlen = 0;
|
||||
#ifdef _MSC_VER
|
||||
for(std::vector<string>::size_type i = 0; i != v.size(); ++i)
|
||||
#else
|
||||
for(vector<string>::size_type i = 0; i != v.size(); ++i)
|
||||
#endif
|
||||
maxlen = max(maxlen, v[i].size());
|
||||
return maxlen;
|
||||
}
|
||||
|
||||
vector<string> frame(const vector<string>& v)
|
||||
{
|
||||
vector<string> ret;
|
||||
string::size_type maxlen = width(v);
|
||||
string border(maxlen + 4, '*');
|
||||
|
||||
// write the top border
|
||||
ret.push_back(border);
|
||||
|
||||
// write each interior row, bordered by an asterisk and a space
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
#else
|
||||
for (vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
#endif
|
||||
ret.push_back("* " + v[i] +
|
||||
string(maxlen - v[i].size(), ' ') + " *");
|
||||
}
|
||||
|
||||
// write the bottom border
|
||||
ret.push_back(border);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<string> vcat(const vector<string>& top,
|
||||
const vector<string>& bottom)
|
||||
{
|
||||
// copy the `top' picture
|
||||
vector<string> ret = top;
|
||||
|
||||
// copy entire `bottom' picture
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::const_iterator it = bottom.begin();
|
||||
#else
|
||||
for (vector<string>::const_iterator it = bottom.begin();
|
||||
#endif
|
||||
it != bottom.end(); ++it)
|
||||
ret.push_back(*it);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<string>
|
||||
hcat(const vector<string>& left, const vector<string>& right)
|
||||
{
|
||||
vector<string> ret;
|
||||
|
||||
// add 1 to leave a space between pictures
|
||||
string::size_type width1 = width(left) + 1;
|
||||
|
||||
// indices to look at elements from `left' and `right' respectively
|
||||
#ifdef _MSC_VER
|
||||
std::vector<string>::size_type i = 0, j = 0;
|
||||
#else
|
||||
vector<string>::size_type i = 0, j = 0;
|
||||
#endif
|
||||
string s;
|
||||
// continue until we've seen all rows from both pictures
|
||||
while (i != left.size() || j != right.size()) {
|
||||
// construct new `string' to hold characters from both pictures
|
||||
//string s;
|
||||
|
||||
// copy a row from the left-hand side, if there is one
|
||||
if (i != left.size())
|
||||
s = left[i++];
|
||||
|
||||
// pad to full width
|
||||
s += string(width1 - s.size(), ' ');
|
||||
|
||||
// copy a row from the right-hand side, if there is one
|
||||
if (j != right.size())
|
||||
s += right[j++];
|
||||
|
||||
// add `s' to the picture we're creating
|
||||
ret.push_back(s);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
17
Chapter 5/5-8例题改/pics.h
Normal file
17
Chapter 5/5-8例题改/pics.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef GUARD_pics_h
|
||||
#define GUARD_pics_h
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::string::size_type width(const std::vector<std::string>& v);
|
||||
|
||||
std::vector<std::string> frame(const std::vector<std::string>& v);
|
||||
|
||||
std::vector<std::string> vcat(const std::vector<std::string>& top,
|
||||
const std::vector<std::string>& bottom);
|
||||
|
||||
std::vector<std::string> hcat(const std::vector<std::string>& left,
|
||||
const std::vector<std::string>& right);
|
||||
|
||||
#endif
|
238
Chapter 6/6.1.cpp
Normal file
238
Chapter 6/6.1.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector> //动态数组
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::max;
|
||||
|
||||
|
||||
vector<string> split(const string& s) { //分割字符串,按空格分割成单词,并存储在vector<string>中
|
||||
vector<string> ret;
|
||||
typedef string::size_type string_size;
|
||||
string_size i = 0;
|
||||
|
||||
while (i != s.size()) {
|
||||
//忽略前段的空白:[先前的i,i)中全部字符都是空格
|
||||
while (i != s.size() && isspace(s[i])) {
|
||||
i++;
|
||||
}
|
||||
//找出下一个单词的终结点
|
||||
string_size j = i;
|
||||
//[先前的j,j)中的任意字符都不是空格
|
||||
while (j != s.size() && !isspace(s[j])) {
|
||||
j++;
|
||||
}
|
||||
//找到了一些非空白符
|
||||
if (i != j) {
|
||||
ret.push_back(s.substr(i, j - i));
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//找出向量中最长字符串的长度
|
||||
string::size_type width(const vector<string>& v) { //计算字符串向量中最长字符串的长度
|
||||
string::size_type maxlen = 0;
|
||||
for (vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
maxlen = max(maxlen, v[i].size());
|
||||
}
|
||||
return maxlen;
|
||||
}
|
||||
|
||||
vector<string> frame(const vector<string>& v) {
|
||||
vector<string> ret;
|
||||
string::size_type maxlen = width(v); //计算每行最长字符串长度
|
||||
//输出顶部边框
|
||||
string border(maxlen + 4, '*');
|
||||
|
||||
//输出内部的行,每行都用一个星号和一个空格来框起来
|
||||
ret.push_back(border);
|
||||
//使用迭代器实现
|
||||
vector<string>::const_iterator iter = v.begin();
|
||||
while (iter != v.end()) { //每行输出中间的字符串,两边填充空格,使其宽度一致
|
||||
ret.push_back("* " + (*iter) + string(maxlen - iter->size(), ' ') + " *");
|
||||
iter++;
|
||||
}
|
||||
ret.push_back(border);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//纵向连接
|
||||
vector<string> vcat(const vector<string>& top, const vector<string>& bottom) {
|
||||
vector<string> ret = top;
|
||||
ret.insert(ret.end(), bottom.begin(), bottom.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
//横向连接
|
||||
vector<string> hcat(const vector<string>& left, const vector<string>& right) {
|
||||
vector<string>ret;
|
||||
//在两幅图案之间留空格
|
||||
string::size_type width1 = width(left) + 1;
|
||||
//用于遍历left和right的索引
|
||||
//使用迭代器
|
||||
vector<string>::const_iterator i, j;
|
||||
i = left.begin();
|
||||
j = right.begin();
|
||||
while (i != left.end() || j != right.end()) {
|
||||
string s;
|
||||
if (i != left.end()) {
|
||||
s = *i++;
|
||||
}
|
||||
|
||||
s += string(width1 - s.size(), ' ');
|
||||
|
||||
if (j != right.end()) {
|
||||
s += *j++;
|
||||
}
|
||||
ret.push_back(s);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
string s;
|
||||
while (getline(cin, s)) {
|
||||
vector<string> v = split(s);
|
||||
vector<string> fra = frame(v); //调用frame对分割后的单词添加框架
|
||||
vector<string> col, row;
|
||||
col = vcat(v, fra);
|
||||
row = hcat(v, fra); //通过hcat将分割文本和框架化文本并排显示并输出到屏幕上
|
||||
for (vector<string>::size_type j = 0; j != row.size(); ++j) {
|
||||
cout << row[j] << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组(vector)容器库
|
||||
#include <list> // 引入链表容器库(未使用)
|
||||
#include <algorithm> // 引入算法库(用于std::max)
|
||||
#include <cctype> // 引入字符处理函数库(用于std::isspace)
|
||||
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::max;
|
||||
|
||||
// 按空格分割字符串,返回分割后的单词向量
|
||||
vector<string> split(const string& s) {
|
||||
vector<string> ret; // 存储分割结果
|
||||
typedef string::size_type string_size; // 定义字符串长度的类型
|
||||
string_size i = 0;
|
||||
|
||||
while (i != s.size()) {
|
||||
// 跳过空格
|
||||
while (i != s.size() && isspace(s[i])) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// 找到下一个单词的结束位置
|
||||
string_size j = i;
|
||||
while (j != s.size() && !isspace(s[j])) {
|
||||
j++;
|
||||
}
|
||||
|
||||
// 如果找到单词,将其添加到结果中
|
||||
if (i != j) {
|
||||
ret.push_back(s.substr(i, j - i)); // 提取单词并存入向量
|
||||
i = j; // 更新索引位置
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 找出向量中最长字符串的长度
|
||||
string::size_type width(const vector<string>& v) {
|
||||
string::size_type maxlen = 0; // 初始化最大长度为0
|
||||
for (vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
maxlen = max(maxlen, v[i].size()); // 更新最大长度
|
||||
}
|
||||
return maxlen;
|
||||
}
|
||||
|
||||
// 为向量中的字符串添加框架(边框)
|
||||
vector<string> frame(const vector<string>& v) {
|
||||
vector<string> ret; // 存储框架化后的字符串
|
||||
string::size_type maxlen = width(v); // 计算最长字符串长度
|
||||
string border(maxlen + 4, '*'); // 定义边框字符串
|
||||
|
||||
ret.push_back(border); // 添加顶部边框
|
||||
vector<string>::const_iterator iter = v.begin();
|
||||
|
||||
while (iter != v.end()) {
|
||||
// 每行添加左右边框和适当的填充
|
||||
ret.push_back("* " + (*iter) + string(maxlen - iter->size(), ' ') + " *");
|
||||
iter++;
|
||||
}
|
||||
ret.push_back(border); // 添加底部边框
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 纵向连接两个字符串向量
|
||||
vector<string> vcat(const vector<string>& top, const vector<string>& bottom) {
|
||||
vector<string> ret = top; // 初始化结果为顶部向量
|
||||
ret.insert(ret.end(), bottom.begin(), bottom.end()); // 添加底部向量
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 横向连接两个字符串向量
|
||||
vector<string> hcat(const vector<string>& left, const vector<string>& right) {
|
||||
vector<string> ret;
|
||||
string::size_type width1 = width(left) + 1; // 为左侧添加一个空格的宽度
|
||||
vector<string>::const_iterator i = left.begin(), j = right.begin();
|
||||
|
||||
// 同时遍历左、右向量
|
||||
while (i != left.end() || j != right.end()) {
|
||||
string s;
|
||||
|
||||
if (i != left.end()) {
|
||||
s = *i++; // 获取左侧字符串
|
||||
}
|
||||
|
||||
s += string(width1 - s.size(), ' '); // 填充空格以对齐
|
||||
|
||||
if (j != right.end()) {
|
||||
s += *j++; // 添加右侧字符串
|
||||
}
|
||||
|
||||
ret.push_back(s); // 将拼接后的字符串添加到结果
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
string s;
|
||||
while (getline(cin, s)) {
|
||||
// 按空格分割输入字符串
|
||||
vector<string> v = split(s);
|
||||
// 为分割后的字符串添加框架
|
||||
vector<string> fra = frame(v);
|
||||
// 纵向连接原始字符串和框架化字符串
|
||||
vector<string> col = vcat(v, fra);
|
||||
// 横向连接原始字符串和框架化字符串
|
||||
vector<string> row = hcat(v, fra);
|
||||
|
||||
// 输出横向连接后的结果
|
||||
for (vector<string>::size_type j = 0; j != row.size(); ++j) {
|
||||
cout << row[j] << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
48
Chapter 6/6.9.cpp
Normal file
48
Chapter 6/6.9.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include <iostream>
|
||||
#include <vector> //动态数组
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
|
||||
using std::cin;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
using std::vector;
|
||||
using std::accumulate; //accumulate()函数返回数组内元素的累积值
|
||||
using std::string;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
vector<string> v = { "zhang", "meng", "nan" , "1220310013"};
|
||||
string str; //创建空字符串
|
||||
str = accumulate(v.begin(), v.end(), str); //将v中所有字符加入str中
|
||||
cout << str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <vector> // 引入动态数组(vector)容器库
|
||||
#include <numeric> // 引入numeric库,提供accumulate函数
|
||||
#include <string> // 引入字符串库
|
||||
|
||||
using std::cin;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
using std::vector;
|
||||
using std::accumulate; // 引入accumulate函数,用于累加容器内的元素
|
||||
using std::string;
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
// 初始化一个包含字符串的向量
|
||||
vector<string> v = { "zhang", "meng", "nan", "1220310013" };
|
||||
|
||||
string str; // 创建一个空字符串,用于存储累积的结果
|
||||
|
||||
// 使用accumulate函数将vector v中的所有字符串连接起来
|
||||
// accumulate的第三个参数是累积的初始值,空字符串str用于开始累积
|
||||
str = accumulate(v.begin(), v.end(), str);
|
||||
|
||||
// 输出累积后的字符串
|
||||
cout << str; // 输出:"zhangmengnan1220310013"
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
148
Chapter 7/7-3/7-3xref.cpp
Normal file
148
Chapter 7/7-3/7-3xref.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::cin; using std::cout;
|
||||
using std::endl; using std::getline;
|
||||
using std::istream; using std::string;
|
||||
using std::vector; using std::map;
|
||||
using std::set;
|
||||
|
||||
// find all the lines that refer to each word in the input
|
||||
map<string, set<int> >
|
||||
xref(istream& in,
|
||||
vector<string> find_words(const string&) = split)
|
||||
{
|
||||
string line;
|
||||
int line_number = 0;
|
||||
map<string, set<int> > ret;
|
||||
|
||||
// read the next line
|
||||
while (getline(in, line)) {
|
||||
++line_number;
|
||||
|
||||
// break the input line into words
|
||||
vector<string> words = find_words(line);
|
||||
|
||||
// remember that each word occurs on the current line
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::const_iterator it = words.begin();
|
||||
#else
|
||||
for (vector<string>::const_iterator it = words.begin();
|
||||
#endif
|
||||
it != words.end(); ++it)
|
||||
ret[*it].insert(line_number);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// call `xref' using `split' by default
|
||||
map<string, set<int> > ret = xref(cin);
|
||||
|
||||
// write the results
|
||||
#ifdef _MSC_VER
|
||||
for (std::map<string, set<int> >::const_iterator it = ret.begin();
|
||||
#else
|
||||
for (map<string, set<int> >::const_iterator it = ret.begin();
|
||||
#endif
|
||||
it != ret.end(); ++it) {
|
||||
// write the word
|
||||
cout << it->first << " occurs on line(s): ";
|
||||
|
||||
// followed by one or more line numbers
|
||||
#ifdef _MSC_VER
|
||||
std::set<int>::const_iterator line_it = it->second.begin();
|
||||
#else
|
||||
set<int>::const_iterator line_it = it->second.begin();
|
||||
#endif
|
||||
cout << *line_it; // write the first line number
|
||||
|
||||
++line_it;
|
||||
// write the rest of the line numbers, if any
|
||||
while (line_it != it->second.end()) {
|
||||
cout << ", " << *line_it;
|
||||
++line_it;
|
||||
}
|
||||
// write a new line to separate each word from the next
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <map> // 引入映射容器库(map)用于存储每个单词与其出现行数的对应关系
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组(vector)容器库
|
||||
#include <set> // 引入集合容器库(set)用于存储行号
|
||||
|
||||
#include "split.h" // 引入自定义头文件split.h,包含split函数的声明
|
||||
|
||||
using std::cin; // 引入标准输入流
|
||||
using std::cout; // 引入标准输出流
|
||||
using std::endl; // 引入换行符
|
||||
using std::getline; // 引入getline函数,用于逐行读取输入
|
||||
using std::istream; // 引入输入流类
|
||||
using std::string; // 引入字符串类
|
||||
using std::vector; // 引入动态数组类
|
||||
using std::map; // 引入映射容器类
|
||||
using std::set; // 引入集合容器类
|
||||
|
||||
// xref 函数:查找每个单词在输入中出现的行号
|
||||
map<string, set<int> >
|
||||
xref(istream& in, // 输入流(默认为cin)
|
||||
vector<string> find_words(const string&) = split) // 使用split函数分割单词(默认)
|
||||
{
|
||||
string line; // 用于存储每行的文本
|
||||
int line_number = 0; // 当前行号
|
||||
map<string, set<int>> ret; // 存储单词及其出现的行号,使用map<单词, set<行号>>结构
|
||||
|
||||
// 逐行读取输入
|
||||
while (getline(in, line)) {
|
||||
++line_number; // 行号自增
|
||||
|
||||
// 将当前行拆分为单词(使用find_words函数,默认是split)
|
||||
vector<string> words = find_words(line);
|
||||
|
||||
// 遍历当前行中的每个单词,将其对应的行号插入到map中
|
||||
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it)
|
||||
ret[*it].insert(line_number); // 将单词及其行号存入map
|
||||
}
|
||||
return ret; // 返回map,包含每个单词及其出现的行号
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 调用xref函数,默认使用split函数进行单词拆分,输入来自cin
|
||||
map<string, set<int>> ret = xref(cin);
|
||||
|
||||
// 输出结果:每个单词及其出现的行号
|
||||
for (map<string, set<int>>::const_iterator it = ret.begin(); it != ret.end(); ++it) {
|
||||
// 输出单词
|
||||
cout << it->first << " occurs on line(s): ";
|
||||
|
||||
// 输出该单词出现的所有行号
|
||||
set<int>::const_iterator line_it = it->second.begin();
|
||||
cout << *line_it; // 输出第一个行号
|
||||
|
||||
++line_it;
|
||||
// 输出其余行号
|
||||
while (line_it != it->second.end()) {
|
||||
cout << ", " << *line_it;
|
||||
++line_it;
|
||||
}
|
||||
|
||||
// 输出换行符,以分隔每个单词的输出
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
43
Chapter 7/7-3/split.cpp
Normal file
43
Chapter 7/7-3/split.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using std::isspace;
|
||||
#endif
|
||||
|
||||
vector<string> split(const string& s)
|
||||
{
|
||||
vector<string> ret;
|
||||
typedef string::size_type string_size;
|
||||
string_size i = 0;
|
||||
|
||||
// invariant: we have processed characters `['original value of `i', `i)'
|
||||
while (i != s.size()) {
|
||||
// ignore leading blanks
|
||||
// invariant: characters in range `['original `i', current `i)' are all spaces
|
||||
while (i != s.size() && isspace(s[i]))
|
||||
++i;
|
||||
|
||||
// find end of next word
|
||||
string_size j = i;
|
||||
// invariant: none of the characters in range `['original `j', current `j)' is a space
|
||||
while (j != s.size() && !isspace(s[j]))
|
||||
++j;
|
||||
|
||||
// if we found some nonwhitespace characters
|
||||
if (i != j) {
|
||||
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
|
||||
ret.push_back(s.substr(i, j - i));
|
||||
i = j;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
8
Chapter 7/7-3/split.h
Normal file
8
Chapter 7/7-3/split.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef GUARD_split_h
|
||||
#define GUARD_split_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
std::vector<std::string> split(const std::string&);
|
||||
|
||||
#endif
|
251
Chapter 8/8-5gen_sentence/8-5grammar.cpp
Normal file
251
Chapter 8/8-5gen_sentence/8-5grammar.cpp
Normal file
@ -0,0 +1,251 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4503) // `silence compiler complaints about generated names being too long'
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
#include <time.h>
|
||||
|
||||
using std::istream; using std::cin;
|
||||
using std::copy; using std::cout;
|
||||
using std::endl; using std::find;
|
||||
using std::getline; using std::logic_error;
|
||||
using std::map; using std::string;
|
||||
using std::vector; using std::domain_error;
|
||||
using std::rand;
|
||||
|
||||
typedef vector<string> Rule;
|
||||
typedef vector<Rule> Rule_collection;
|
||||
typedef map<string, Rule_collection> Grammar;
|
||||
|
||||
// read a grammar from a given input stream
|
||||
Grammar read_grammar(istream& in)
|
||||
{
|
||||
Grammar ret;
|
||||
string line;
|
||||
|
||||
// read the input
|
||||
while (getline(in, line)) {
|
||||
|
||||
// `split' the input into words
|
||||
vector<string> entry = split(line);
|
||||
|
||||
if (!entry.empty())
|
||||
// use the category to store the associated rule
|
||||
ret[entry[0]].push_back(
|
||||
Rule(entry.begin() + 1, entry.end()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gen_aux(const Grammar&, const string&, vector<string>&);
|
||||
|
||||
int nrand(int);
|
||||
|
||||
vector<string> gen_sentence(const Grammar& g)
|
||||
{
|
||||
vector<string> ret;
|
||||
gen_aux(g, "<sentence>", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool bracketed(const string& s)
|
||||
{
|
||||
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
|
||||
}
|
||||
|
||||
void
|
||||
gen_aux(const Grammar& g, const string& word, vector<string>& ret)
|
||||
{
|
||||
|
||||
if (!bracketed(word)) {
|
||||
ret.push_back(word);
|
||||
} else {
|
||||
// locate the rule that corresponds to `word'
|
||||
Grammar::const_iterator it = g.find(word);
|
||||
if (it == g.end())
|
||||
throw logic_error("empty rule");
|
||||
|
||||
// fetch the set of possible rules
|
||||
const Rule_collection& c = it->second;
|
||||
|
||||
// from which we select one at random
|
||||
const Rule& r = c[nrand(c.size())];
|
||||
|
||||
// recursively expand the selected rule
|
||||
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
|
||||
gen_aux(g, *i, ret);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// generate the sentence
|
||||
vector<string> sentence = gen_sentence(read_grammar(cin));
|
||||
|
||||
// write the first word, if any
|
||||
#ifdef _MSC_VER
|
||||
std::vector<string>::const_iterator it = sentence.begin();
|
||||
#else
|
||||
vector<string>::const_iterator it = sentence.begin();
|
||||
#endif
|
||||
if (!sentence.empty()) {
|
||||
cout << *it;
|
||||
++it;
|
||||
}
|
||||
|
||||
// write the rest of the words, each preceded by a space
|
||||
while (it != sentence.end()) {
|
||||
cout << " " << *it;
|
||||
++it;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return a random integer in the range `[0,' `n)'
|
||||
int nrand(int n)
|
||||
{
|
||||
if (n <= 0 || n > RAND_MAX)
|
||||
throw domain_error("Argument to nrand is out of range");
|
||||
|
||||
const int bucket_size = RAND_MAX / n;
|
||||
int r;
|
||||
|
||||
do r = rand() / bucket_size;
|
||||
while (r >= n);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4503) // 关闭编译器警告,避免对生成的名称过长的抱怨
|
||||
#endif
|
||||
|
||||
#include <algorithm> // 引入算法库,提供常用的算法
|
||||
#include <cstdlib> // 引入C标准库,包含rand()函数
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <map> // 引入映射容器(map)库
|
||||
#include <stdexcept> // 引入标准异常库,提供逻辑错误和域错误等异常
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组(vector)库
|
||||
#include "split.h" // 引入自定义的split.h头文件(假定提供了字符串拆分功能)
|
||||
#include <time.h> // 引入时间库,支持随机数生成
|
||||
|
||||
using std::istream; using std::cin;
|
||||
using std::copy; using std::cout;
|
||||
using std::endl; using std::find;
|
||||
using std::getline; using std::logic_error;
|
||||
using std::map; using std::string;
|
||||
using std::vector; using std::domain_error;
|
||||
using std::rand; // 引入rand函数
|
||||
|
||||
// 定义规则(字符串集合)和语法(规则集合)的类型
|
||||
typedef vector<string> Rule; // 一个规则是字符串的集合
|
||||
typedef vector<Rule> Rule_collection; // 规则集合是规则的集合
|
||||
typedef map<string, Rule_collection> Grammar; // 语法是一个映射:类别 -> 规则集合
|
||||
|
||||
// 从输入流中读取语法并返回
|
||||
Grammar read_grammar(istream& in) {
|
||||
Grammar ret; // 用于存储语法
|
||||
string line;
|
||||
|
||||
// 持续读取每一行
|
||||
while (getline(in, line)) {
|
||||
// 将当前行拆分成单词
|
||||
vector<string> entry = split(line);
|
||||
|
||||
// 如果拆分出的单词不为空,则根据类别存储规则
|
||||
if (!entry.empty())
|
||||
ret[entry[0]].push_back(
|
||||
Rule(entry.begin() + 1, entry.end())); // 使用类别作为key,规则作为value
|
||||
}
|
||||
return ret; // 返回语法
|
||||
}
|
||||
|
||||
// 递归生成句子的辅助函数
|
||||
void gen_aux(const Grammar&, const string&, vector<string>&);
|
||||
|
||||
// 返回一个范围在[0, n)内的随机整数
|
||||
int nrand(int);
|
||||
|
||||
// 生成一个句子,调用gen_aux进行递归生成
|
||||
vector<string> gen_sentence(const Grammar& g) {
|
||||
vector<string> ret;
|
||||
gen_aux(g, "<sentence>", ret); // 从<sentence>开始生成句子
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 判断一个字符串是否是被尖括号包围的
|
||||
bool bracketed(const string& s) {
|
||||
return s.size() > 1 && s[0] == '<' && s[s.size() - 1] == '>';
|
||||
}
|
||||
|
||||
// 递归地生成句子中的一部分
|
||||
void gen_aux(const Grammar& g, const string& word, vector<string>& ret) {
|
||||
if (!bracketed(word)) {
|
||||
ret.push_back(word); // 如果不是被尖括号包围的单词,直接加入句子
|
||||
}
|
||||
else {
|
||||
// 查找对应的规则
|
||||
Grammar::const_iterator it = g.find(word);
|
||||
if (it == g.end()) // 如果没有找到规则,抛出异常
|
||||
throw logic_error("empty rule");
|
||||
|
||||
// 获取该单词的规则集合
|
||||
const Rule_collection& c = it->second;
|
||||
|
||||
// 从规则集合中随机选择一个规则
|
||||
const Rule& r = c[nrand(c.size())];
|
||||
|
||||
// 对选中的规则中的每个单词进行递归处理
|
||||
for (Rule::const_iterator i = r.begin(); i != r.end(); ++i)
|
||||
gen_aux(g, *i, ret);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 生成句子
|
||||
vector<string> sentence = gen_sentence(read_grammar(cin));
|
||||
|
||||
// 输出第一个单词(如果有)
|
||||
vector<string>::const_iterator it = sentence.begin();
|
||||
if (!sentence.empty()) {
|
||||
cout << *it;
|
||||
++it;
|
||||
}
|
||||
|
||||
// 输出剩余的单词,每个单词前加一个空格
|
||||
while (it != sentence.end()) {
|
||||
cout << " " << *it;
|
||||
++it;
|
||||
}
|
||||
|
||||
cout << endl; // 输出换行
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 返回一个随机整数,范围在[0, n)
|
||||
int nrand(int n) {
|
||||
if (n <= 0 || n > RAND_MAX)
|
||||
throw domain_error("Argument to nrand is out of range");
|
||||
|
||||
const int bucket_size = RAND_MAX / n; // 将随机数均匀分布
|
||||
int r;
|
||||
|
||||
// 确保随机数在有效范围内
|
||||
do r = rand() / bucket_size;
|
||||
while (r >= n);
|
||||
|
||||
return r;
|
||||
}
|
43
Chapter 8/8-5gen_sentence/split.cpp
Normal file
43
Chapter 8/8-5gen_sentence/split.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using std::isspace;
|
||||
#endif
|
||||
|
||||
vector<string> split(const string& s)
|
||||
{
|
||||
vector<string> ret;
|
||||
typedef string::size_type string_size;
|
||||
string_size i = 0;
|
||||
|
||||
// invariant: we have processed characters `['original value of `i', `i)'
|
||||
while (i != s.size()) {
|
||||
// ignore leading blanks
|
||||
// invariant: characters in range `['original `i', current `i)' are all spaces
|
||||
while (i != s.size() && isspace(s[i]))
|
||||
++i;
|
||||
|
||||
// find end of next word
|
||||
string_size j = i;
|
||||
// invariant: none of the characters in range `['original `j', current `j)' is a space
|
||||
while (j != s.size() && !isspace(s[j]))
|
||||
++j;
|
||||
|
||||
// if we found some nonwhitespace characters
|
||||
if (i != j) {
|
||||
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
|
||||
ret.push_back(s.substr(i, j - i));
|
||||
i = j;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
8
Chapter 8/8-5gen_sentence/split.h
Normal file
8
Chapter 8/8-5gen_sentence/split.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef GUARD_split_h
|
||||
#define GUARD_split_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
std::vector<std::string> split(const std::string&);
|
||||
|
||||
#endif
|
108
Chapter 8/8-5gen_sentence/例题改/pics.cpp
Normal file
108
Chapter 8/8-5gen_sentence/例题改/pics.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pics.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::max;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//#include "../minmax.h"
|
||||
#else
|
||||
//using std::max;
|
||||
#endif
|
||||
|
||||
string::size_type width(const vector<string>& v)
|
||||
{
|
||||
string::size_type maxlen = 0;
|
||||
#ifdef _MSC_VER
|
||||
for(std::vector<string>::size_type i = 0; i != v.size(); ++i)
|
||||
#else
|
||||
for(vector<string>::size_type i = 0; i != v.size(); ++i)
|
||||
#endif
|
||||
maxlen = max(maxlen, v[i].size());
|
||||
return maxlen;
|
||||
}
|
||||
|
||||
vector<string> frame(const vector<string>& v)
|
||||
{
|
||||
vector<string> ret;
|
||||
string::size_type maxlen = width(v);
|
||||
string border(maxlen + 4, '*');
|
||||
|
||||
// write the top border
|
||||
ret.push_back(border);
|
||||
|
||||
// write each interior row, bordered by an asterisk and a space
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
#else
|
||||
for (vector<string>::size_type i = 0; i != v.size(); ++i) {
|
||||
#endif
|
||||
ret.push_back("* " + v[i] +
|
||||
string(maxlen - v[i].size(), ' ') + " *");
|
||||
}
|
||||
|
||||
// write the bottom border
|
||||
ret.push_back(border);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<string> vcat(const vector<string>& top,
|
||||
const vector<string>& bottom)
|
||||
{
|
||||
// copy the `top' picture
|
||||
vector<string> ret = top;
|
||||
|
||||
// copy entire `bottom' picture
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::const_iterator it = bottom.begin();
|
||||
#else
|
||||
for (vector<string>::const_iterator it = bottom.begin();
|
||||
#endif
|
||||
it != bottom.end(); ++it)
|
||||
ret.push_back(*it);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<string>
|
||||
hcat(const vector<string>& left, const vector<string>& right)
|
||||
{
|
||||
vector<string> ret;
|
||||
|
||||
// add 1 to leave a space between pictures
|
||||
string::size_type width1 = width(left) + 1;
|
||||
|
||||
// indices to look at elements from `left' and `right' respectively
|
||||
#ifdef _MSC_VER
|
||||
std::vector<string>::size_type i = 0, j = 0;
|
||||
#else
|
||||
vector<string>::size_type i = 0, j = 0;
|
||||
#endif
|
||||
string s;
|
||||
// continue until we've seen all rows from both pictures
|
||||
while (i != left.size() || j != right.size()) {
|
||||
// construct new `string' to hold characters from both pictures
|
||||
//string s;
|
||||
|
||||
// copy a row from the left-hand side, if there is one
|
||||
if (i != left.size())
|
||||
s = left[i++];
|
||||
|
||||
// pad to full width
|
||||
s += string(width1 - s.size(), ' ');
|
||||
|
||||
// copy a row from the right-hand side, if there is one
|
||||
if (j != right.size())
|
||||
s += right[j++];
|
||||
|
||||
// add `s' to the picture we're creating
|
||||
ret.push_back(s);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
17
Chapter 8/8-5gen_sentence/例题改/pics.h
Normal file
17
Chapter 8/8-5gen_sentence/例题改/pics.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef GUARD_pics_h
|
||||
#define GUARD_pics_h
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::string::size_type width(const std::vector<std::string>& v);
|
||||
|
||||
std::vector<std::string> frame(const std::vector<std::string>& v);
|
||||
|
||||
std::vector<std::string> vcat(const std::vector<std::string>& top,
|
||||
const std::vector<std::string>& bottom);
|
||||
|
||||
std::vector<std::string> hcat(const std::vector<std::string>& left,
|
||||
const std::vector<std::string>& right);
|
||||
|
||||
#endif
|
85
Chapter 8/8-5gen_sentence/例题改/pics_main.cpp
Normal file
85
Chapter 8/8-5gen_sentence/例题改/pics_main.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pics.h"
|
||||
|
||||
using std::cout;
|
||||
using std::copy;
|
||||
using std::endl;
|
||||
using std::ostream_iterator;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<string> p;
|
||||
p.push_back("this is an");
|
||||
p.push_back("example");
|
||||
p.push_back("to");
|
||||
p.push_back("illustrate");
|
||||
p.push_back("framing");
|
||||
|
||||
ostream_iterator<string>ofile(cout, "\n");
|
||||
copy(p.begin(), p.end(), ofile);
|
||||
cout << endl;
|
||||
|
||||
vector<string> f = frame(p);
|
||||
copy(f.begin(), f.end(), ofile); cout << endl;
|
||||
|
||||
vector<string> h = hcat(p,frame(p));
|
||||
copy(h.begin(), h.end(), ofile);
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <algorithm> // 引入算法库,提供常用的算法
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <iterator> // 引入迭代器库
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组(vector)库
|
||||
|
||||
#include "pics.h" // 引入自定义的 pics.h 库(假设此库包含框架生成和拼接相关的功能)
|
||||
|
||||
using std::cout; // 使用标准输出流
|
||||
using std::copy; // 引入copy算法
|
||||
using std::endl; // 引入换行符
|
||||
using std::ostream_iterator; // 引入输出流迭代器,用于输出容器的内容
|
||||
using std::string; // 使用字符串类型
|
||||
using std::vector; // 使用vector容器
|
||||
|
||||
int main() {
|
||||
// 创建一个vector<string>类型的容器 p,存储字符串
|
||||
vector<string> p;
|
||||
p.push_back("this is an"); // 添加一个字符串
|
||||
p.push_back("example"); // 添加一个字符串
|
||||
p.push_back("to"); // 添加一个字符串
|
||||
p.push_back("illustrate"); // 添加一个字符串
|
||||
p.push_back("framing"); // 添加一个字符串
|
||||
|
||||
// 创建输出流迭代器,指定输出到 cout,并且每个元素输出后换行
|
||||
ostream_iterator<string> ofile(cout, "\n");
|
||||
|
||||
// 使用copy算法,将vector p中的内容逐个输出
|
||||
copy(p.begin(), p.end(), ofile);
|
||||
cout << endl; // 输出换行符
|
||||
|
||||
// 对vector p应用框架操作,生成一个新的vector f
|
||||
vector<string> f = frame(p);
|
||||
// 使用copy算法,将vector f中的内容逐个输出
|
||||
copy(f.begin(), f.end(), ofile);
|
||||
cout << endl; // 输出换行符
|
||||
|
||||
// 将vector p和vector f进行横向拼接,生成一个新的vector h
|
||||
vector<string> h = hcat(p, frame(p));
|
||||
// 使用copy算法,将vector h中的内容逐个输出
|
||||
copy(h.begin(), h.end(), ofile);
|
||||
cout << endl; // 输出换行符
|
||||
|
||||
return 0; // 程序正常结束
|
||||
}
|
145
Chapter 8/8-5xref/8-5xref.cpp
Normal file
145
Chapter 8/8-5xref/8-5xref.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::cin; using std::cout;
|
||||
using std::endl; using std::getline;
|
||||
using std::istream; using std::string;
|
||||
using std::vector; using std::map;
|
||||
|
||||
// find all the lines that refer to each word in the input
|
||||
map<string, vector<int> >
|
||||
xref(istream& in,
|
||||
vector<string> find_words(const string&) = split)
|
||||
{
|
||||
string line;
|
||||
int line_number = 0;
|
||||
map<string, vector<int> > ret;
|
||||
|
||||
// read the next line
|
||||
while (getline(in, line)) {
|
||||
++line_number;
|
||||
|
||||
// break the input line into words
|
||||
vector<string> words = find_words(line);
|
||||
|
||||
// remember that each word occurs on the current line
|
||||
#ifdef _MSC_VER
|
||||
for (std::vector<string>::const_iterator it = words.begin();
|
||||
#else
|
||||
for (vector<string>::const_iterator it = words.begin();
|
||||
#endif
|
||||
it != words.end(); ++it)
|
||||
ret[*it].push_back(line_number);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// call `xref' using `split' by default
|
||||
map<string, vector<int> > ret = xref(cin);
|
||||
|
||||
// write the results
|
||||
#ifdef _MSC_VER
|
||||
for (std::map<string, vector<int> >::const_iterator it = ret.begin();
|
||||
#else
|
||||
for (map<string, vector<int> >::const_iterator it = ret.begin();
|
||||
#endif
|
||||
it != ret.end(); ++it) {
|
||||
// write the word
|
||||
cout << it->first << " occurs on line(s): ";
|
||||
|
||||
// followed by one or more line numbers
|
||||
#ifdef _MSC_VER
|
||||
std::vector<int>::const_iterator line_it = it->second.begin();
|
||||
#else
|
||||
vector<int>::const_iterator line_it = it->second.begin();
|
||||
#endif
|
||||
cout << *line_it; // write the first line number
|
||||
|
||||
++line_it;
|
||||
// write the rest of the line numbers, if any
|
||||
while (line_it != it->second.end()) {
|
||||
cout << ", " << *line_it;
|
||||
++line_it;
|
||||
}
|
||||
// write a new line to separate each word from the next
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <map> // 引入 map 容器,用于存储每个单词及其出现的行号
|
||||
#include <iostream> // 引入标准输入输出流库
|
||||
#include <string> // 引入字符串库
|
||||
#include <vector> // 引入动态数组库,用于存储每一行的单词
|
||||
|
||||
#include "split.h" // 引入自定义的 split.h 库,假设包含用于分割字符串的函数
|
||||
|
||||
using std::cin; // 使用标准输入流
|
||||
using std::cout; // 使用标准输出流
|
||||
using std::endl; // 使用换行符
|
||||
using std::getline; // 使用getline函数读取整行输入
|
||||
using std::istream; // 使用输入流
|
||||
using std::string; // 使用字符串类型
|
||||
using std::vector; // 使用vector容器
|
||||
using std::map; // 使用map容器
|
||||
|
||||
// xref函数:用来查找每个单词在文本中出现的行号
|
||||
// 参数:输入流 in 和一个函数指针 find_words,用于分割每行的单词(默认为 split 函数)
|
||||
map<string, vector<int> >
|
||||
xref(istream& in,
|
||||
vector<string> find_words(const string&) = split)
|
||||
{
|
||||
string line; // 用来存储每一行的文本
|
||||
int line_number = 0; // 行号
|
||||
map<string, vector<int> > ret; // 用map来存储每个单词及其对应的行号
|
||||
|
||||
// 按行读取输入
|
||||
while (getline(in, line)) {
|
||||
++line_number; // 增加行号
|
||||
|
||||
// 调用find_words函数将一行文本分割成单词
|
||||
vector<string> words = find_words(line);
|
||||
|
||||
// 将当前行号添加到每个单词的对应位置
|
||||
for (vector<string>::const_iterator it = words.begin(); it != words.end(); ++it)
|
||||
ret[*it].push_back(line_number); // 将单词和行号对应起来
|
||||
}
|
||||
return ret; // 返回包含每个单词及其行号的map
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 调用 xref 函数,默认使用 split 来分割单词
|
||||
map<string, vector<int> > ret = xref(cin);
|
||||
|
||||
// 输出结果
|
||||
for (map<string, vector<int> >::const_iterator it = ret.begin(); it != ret.end(); ++it) {
|
||||
// 输出单词
|
||||
cout << it->first << " occurs on line(s): ";
|
||||
|
||||
// 获取并输出单词出现的行号
|
||||
vector<int>::const_iterator line_it = it->second.begin();
|
||||
cout << *line_it; // 输出第一个行号
|
||||
|
||||
++line_it;
|
||||
// 输出其余的行号
|
||||
while (line_it != it->second.end()) {
|
||||
cout << ", " << *line_it;
|
||||
++line_it;
|
||||
}
|
||||
// 换行
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0; // 程序结束
|
||||
}
|
||||
|
43
Chapter 8/8-5xref/split.cpp
Normal file
43
Chapter 8/8-5xref/split.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using std::isspace;
|
||||
#endif
|
||||
|
||||
vector<string> split(const string& s)
|
||||
{
|
||||
vector<string> ret;
|
||||
typedef string::size_type string_size;
|
||||
string_size i = 0;
|
||||
|
||||
// invariant: we have processed characters `['original value of `i', `i)'
|
||||
while (i != s.size()) {
|
||||
// ignore leading blanks
|
||||
// invariant: characters in range `['original `i', current `i)' are all spaces
|
||||
while (i != s.size() && isspace(s[i]))
|
||||
++i;
|
||||
|
||||
// find end of next word
|
||||
string_size j = i;
|
||||
// invariant: none of the characters in range `['original `j', current `j)' is a space
|
||||
while (j != s.size() && !isspace(s[j]))
|
||||
++j;
|
||||
|
||||
// if we found some nonwhitespace characters
|
||||
if (i != j) {
|
||||
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
|
||||
ret.push_back(s.substr(i, j - i));
|
||||
i = j;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
8
Chapter 8/8-5xref/split.h
Normal file
8
Chapter 8/8-5xref/split.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef GUARD_split_h
|
||||
#define GUARD_split_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
std::vector<std::string> split(const std::string&);
|
||||
|
||||
#endif
|
@ -0,0 +1,45 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "split.h"
|
||||
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
// 函数:反转字符串
|
||||
string reverseString(const string& s) {
|
||||
return string(s.rbegin(), s.rend());
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 读取输入文本
|
||||
cout << "输入一段文本: ";
|
||||
string input;
|
||||
std::getline(cin, input);
|
||||
|
||||
// 拆分文本为单词
|
||||
vector<string> words = split(input);
|
||||
|
||||
// 对每个单词进行反转
|
||||
for (auto& word : words) {
|
||||
word = reverseString(word);
|
||||
}
|
||||
|
||||
// 按照反转后的单词排序
|
||||
std::sort(words.begin(), words.end());
|
||||
|
||||
// 输出排序后的单词,保持与原输入格式一致
|
||||
for (size_t i = 0; i < words.size(); ++i) {
|
||||
if (i > 0) {
|
||||
cout << " "; // 单词间加空格
|
||||
}
|
||||
cout << words[i];
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "split.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using std::isspace;
|
||||
#endif
|
||||
|
||||
vector<string> split(const string& s)
|
||||
{
|
||||
vector<string> ret;
|
||||
typedef string::size_type string_size;
|
||||
string_size i = 0;
|
||||
|
||||
// invariant: we have processed characters `['original value of `i', `i)'
|
||||
while (i != s.size()) {
|
||||
// ignore leading blanks
|
||||
// invariant: characters in range `['original `i', current `i)' are all spaces
|
||||
while (i != s.size() && isspace(s[i]))
|
||||
++i;
|
||||
|
||||
// find end of next word
|
||||
string_size j = i;
|
||||
// invariant: none of the characters in range `['original `j', current `j)' is a space
|
||||
while (j != s.size() && !isspace(s[j]))
|
||||
++j;
|
||||
|
||||
// if we found some nonwhitespace characters
|
||||
if (i != j) {
|
||||
// copy from `s' starting at `i' and taking `j' `\-' `i' chars
|
||||
ret.push_back(s.substr(i, j - i));
|
||||
i = j;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
#ifndef GUARD_split_h
|
||||
#define GUARD_split_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
std::vector<std::string> split(const std::string&);
|
||||
|
||||
#endif
|
@ -0,0 +1,41 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "urls.h"
|
||||
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::sort;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
int main() {
|
||||
// 输入文本
|
||||
cout << "输入一段文本: ";
|
||||
string input;
|
||||
std::getline(cin, input);
|
||||
|
||||
// 提取所有 URL
|
||||
vector<string> urls = find_urls(input);
|
||||
|
||||
// 筛选出以 http:// 或 https:// 开头的 URL
|
||||
vector<string> http_urls;
|
||||
for (const string& url : urls) {
|
||||
if (url.find("http://") == 0 || url.find("https://") == 0) {
|
||||
http_urls.push_back(url);
|
||||
}
|
||||
}
|
||||
|
||||
// 按字母顺序排序
|
||||
sort(http_urls.begin(), http_urls.end());
|
||||
|
||||
// 输出结果
|
||||
cout << "排序后的 HTTP URLs:" << endl;
|
||||
for (const string& url : http_urls) {
|
||||
cout << url << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "urls.h"
|
||||
|
||||
using std::find;
|
||||
using std::find_if;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using std::isalnum;
|
||||
using std::isalpha;
|
||||
using std::isdigit;
|
||||
#endif
|
||||
|
||||
using std::search;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
bool not_url_char(char);
|
||||
|
||||
string::const_iterator
|
||||
url_end(string::const_iterator, string::const_iterator);
|
||||
|
||||
string::const_iterator
|
||||
url_beg(string::const_iterator, string::const_iterator);
|
||||
vector<string> find_urls(const string& s)
|
||||
{
|
||||
vector<string> ret;
|
||||
typedef string::const_iterator iter;
|
||||
iter b = s.begin(), e = s.end();
|
||||
|
||||
// look through the entire input
|
||||
while (b != e) {
|
||||
|
||||
// look for one or more letters followed by `://'
|
||||
b = url_beg(b, e);
|
||||
|
||||
// if we found it
|
||||
if (b != e) {
|
||||
// get the rest of the \s-1URL\s0
|
||||
iter after = url_end(b, e);
|
||||
|
||||
// remember the \s-1URL\s0
|
||||
ret.push_back(string(b, after));
|
||||
|
||||
// advance `b' and check for more \s-1URL\s0s on this line
|
||||
b = after;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
string::const_iterator
|
||||
url_end(string::const_iterator b, string::const_iterator e)
|
||||
{
|
||||
return find_if(b, e, not_url_char);
|
||||
}
|
||||
|
||||
bool not_url_char(char c)
|
||||
{
|
||||
// characters, in addition to alphanumerics, that can appear in a \s-1URL\s0
|
||||
static const string url_ch = "~;/?:@=&$-_.+!*'(),";
|
||||
|
||||
// see whether `c' can appear in a \s-1URL\s0 and return the negative
|
||||
return !(isalnum(c) ||
|
||||
find(url_ch.begin(), url_ch.end(), c) != url_ch.end());
|
||||
}
|
||||
|
||||
string::const_iterator
|
||||
url_beg(string::const_iterator b, string::const_iterator e)
|
||||
{
|
||||
static const string sep = "://";
|
||||
|
||||
typedef string::const_iterator iter;
|
||||
|
||||
// `i' marks where the separator was found
|
||||
iter i = b;
|
||||
|
||||
while ((i = search(i, e, sep.begin(), sep.end())) != e) {
|
||||
|
||||
// make sure the separator isn't at the beginning or end of the line
|
||||
if (i != b && i + sep.size() != e) {
|
||||
|
||||
// `beg' marks the beginning of the protocol-name
|
||||
iter beg = i;
|
||||
while (beg != b && isalpha(beg[-1]))
|
||||
--beg;
|
||||
|
||||
// is there at least one appropriate character before and after the separator?
|
||||
if (beg != i && !not_url_char(i[sep.size()]))
|
||||
return beg;
|
||||
}
|
||||
|
||||
// the separator we found wasn't part of a \s-1URL\s0; advance `i' past this separator
|
||||
i += sep.size();
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#ifndef GUARD_urls_h
|
||||
#define GUARD_urls_h
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
std::vector<std::string> find_urls(const std::string& s);
|
||||
|
||||
#endif
|
@ -0,0 +1,37 @@
|
||||
// source file for `Student_info'-related functions
|
||||
#include "Student_info.h"
|
||||
|
||||
using std::istream; using std::vector;
|
||||
|
||||
bool compare(const Student_info& x, const Student_info& y)
|
||||
{
|
||||
return x.name < y.name;
|
||||
}
|
||||
|
||||
istream& read(istream& is, Student_info& s)
|
||||
{
|
||||
// read and store the student's name and midterm and final exam grades
|
||||
is >> s.name >> s.midterm >> s.final;
|
||||
|
||||
read_hw(is, s.homework); // read and store all the student's homework grades
|
||||
return is;
|
||||
}
|
||||
|
||||
// read homework grades from an input stream into a `vector<double>'
|
||||
istream& read_hw(istream& in, vector<double>& hw)
|
||||
{
|
||||
if (in) {
|
||||
// get rid of previous contents
|
||||
hw.clear();
|
||||
|
||||
// read homework grades
|
||||
double x;
|
||||
while (in >> x)
|
||||
hw.push_back(x);
|
||||
|
||||
// clear the stream so that input will work for the next student
|
||||
in.clear();
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
#ifndef GUARD_Student_info
|
||||
#define GUARD_Student_info
|
||||
|
||||
// `Student_info.h' header file
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct Student_info {
|
||||
std::string name;
|
||||
double midterm, final;
|
||||
std::vector<double> homework;
|
||||
};
|
||||
|
||||
bool compare(const Student_info&, const Student_info&);
|
||||
std::istream& read(std::istream&, Student_info&);
|
||||
std::istream& read_hw(std::istream&, std::vector<double>&);
|
||||
#endif
|
||||
|
@ -0,0 +1,41 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include "grade.h"
|
||||
#include "median.h"
|
||||
#include "Student_info.h"
|
||||
|
||||
using std::domain_error; using std::vector;
|
||||
|
||||
|
||||
// compute a student's overall grade from midterm and final exam grades and homework grade
|
||||
double grade(double midterm, double final, double homework)
|
||||
{
|
||||
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
|
||||
}
|
||||
|
||||
// compute a student's overall grade from midterm and final exam grades
|
||||
// and vector of homework grades.
|
||||
// this function does not copy its argument, because `median' does so for us.
|
||||
double grade(double midterm, double final, const vector<double>& hw)
|
||||
{
|
||||
if (hw.size() == 0)
|
||||
throw domain_error("student has done no homework");
|
||||
return grade(midterm, final, median(hw));
|
||||
}
|
||||
|
||||
double grade(const Student_info& s)
|
||||
{
|
||||
return grade(s.midterm, s.final, s.homework);
|
||||
}
|
||||
|
||||
// predicate to determine whether a student failed
|
||||
bool fgrade(const Student_info& s)
|
||||
{
|
||||
return grade(s) < 60;
|
||||
}
|
||||
|
||||
bool pgrade(const Student_info& s)
|
||||
{
|
||||
return !fgrade(s);
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
#ifndef GUARD_grade_h
|
||||
#define GUARD_grade_h
|
||||
|
||||
#include <vector>
|
||||
#include "Student_info.h"
|
||||
|
||||
double grade(double, double, double);
|
||||
double grade(double, double, const std::vector<double>&);
|
||||
double grade(const Student_info&);
|
||||
|
||||
bool pgrade(const Student_info&);
|
||||
bool fgrade(const Student_info&);
|
||||
|
||||
#endif
|
@ -0,0 +1,57 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "Student_info.h"
|
||||
#include "grade.h"
|
||||
|
||||
using std::cin;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
// 定义常量:及格分数
|
||||
const double PASS_GRADE = 60.0;
|
||||
|
||||
int main() {
|
||||
vector<Student_info> students;
|
||||
Student_info record;
|
||||
|
||||
// 读取学生信息
|
||||
cout << "期中成绩占比20%、期末成绩占比40%,平时成绩占比40%):" << endl;
|
||||
cout << "输入学生信息(姓名、期中成绩、期末成绩,平时成绩):" << endl;
|
||||
cout << "输入Ctrl+z后回车退出。" << endl;
|
||||
|
||||
while (read(cin, record)) {
|
||||
students.push_back(record);
|
||||
}
|
||||
|
||||
// 将学生分为及格和不及格两组
|
||||
vector<Student_info> pass, fail;
|
||||
for (const auto& student : students) {
|
||||
if (grade(student) >= PASS_GRADE) {
|
||||
pass.push_back(student);
|
||||
}
|
||||
else {
|
||||
fail.push_back(student);
|
||||
}
|
||||
}
|
||||
|
||||
// 按名字排序
|
||||
std::sort(pass.begin(), pass.end(), compare);
|
||||
std::sort(fail.begin(), fail.end(), compare);
|
||||
|
||||
// 输出及格学生信息
|
||||
cout << "合格学生:" << endl;
|
||||
for (const auto& student : pass) {
|
||||
cout << student.name << ": 总成绩 = " << grade(student) << endl;
|
||||
}
|
||||
|
||||
// 输出不及格学生信息
|
||||
cout << "不合格学生:" << endl;
|
||||
for (const auto& student : fail) {
|
||||
cout << student.name << ": 总成绩 = " << grade(student) << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
// source file for the `median' function
|
||||
#include <algorithm> // to get the declaration of `sort'
|
||||
#include <stdexcept> // to get the declaration of `domain_error'
|
||||
#include <vector> // to get the declaration of `vector'
|
||||
|
||||
using std::domain_error; using std::sort; using std::vector;
|
||||
|
||||
#include "median.h"
|
||||
|
||||
// compute the median of a `vector<double>'
|
||||
// note that calling this function copies the entire argument `vector'
|
||||
double median(vector<double> vec)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
typedef std::vector<double>::size_type vec_sz;
|
||||
#else
|
||||
typedef vector<double>::size_type vec_sz;
|
||||
#endif
|
||||
|
||||
vec_sz size = vec.size();
|
||||
if (size == 0)
|
||||
throw domain_error("median of an empty vector");
|
||||
|
||||
sort(vec.begin(), vec.end());
|
||||
|
||||
vec_sz mid = size/2;
|
||||
|
||||
return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
#ifndef GUARD_median_h
|
||||
#define GUARD_median_h
|
||||
|
||||
// `median.h'--final version
|
||||
#include <vector>
|
||||
double median(std::vector<double>);
|
||||
|
||||
#endif
|
||||
|
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user