网络销售网站有哪些,包头移动官网网站建设,仿站吧,上海传媒公司李健目录
#x1f33c;面向过程的编程风格 -- 第2章
#x1f348;2.2
#x1f348;2.4
#x1f348;2.5
#x1f348;2.6
#x1f33c;泛型编程风格 -- 第3章
#x1f34d;3.1
#x1f34d;3.4
前言
要求
完整代码
输入输出 #x1f33c;面向过程的编程风…目录
面向过程的编程风格 -- 第2章
2.2
2.4
2.5
2.6
泛型编程风格 -- 第3章
3.1
3.4
前言
要求
完整代码
输入输出 面向过程的编程风格 -- 第2章
2.2
要求 Pentagonal 数列的求值公式 P(n) n(3n - 1) / 2借此产生1,5,12,22,35等元素值。试定义一个函数利用上述公式将产生的元素放到用户传入的 vector 中元素个数由用户指定。请检查元素个数的有效性太大可能引发 overflow 问题。接下来编写第二个函数能将给定的 vector 的所有元素一一打印出来。此函数的第二参数接受一个字符串表示存放在 vector 内的数列的类型。最后再写一个 main测试上述两个函数。 代码
#includeiostream
#includestring
#includevector
using namespace std;bool calc_elements(vectorint vec, int pos); // 计算并存储
void display_elems(vectorint vec,const string title, ostream oscout); // 显示元素序列int main()
{vectorint pent; // 存储元素序列const string title(Pentagonal Numeric Series); // 定义一个字符串if (calc_elements(pent, 0)) // 计算并存储位置0的元素display_elems(pent, title); // 打印元素序列if (calc_elements(pent, 8))display_elems(pent, title);if (calc_elements(pent, 14))display_elems(pent, title);if (calc_elements(pent, 138))display_elems(pent, title);
}bool calc_elements(vectorint vec, int pos)
{// 检查元素个数有效性, 防止 overflowif (pos 0 || pos 64) {cerr sorry. Invalid position: posendl;return false;}for (int ix vec.size() 1; ix pos; ix)vec.push_back( (ix*(3*ix-1)) / 2 ); // 插入元素return true;
}void display_elems(vectorint vec,const string title, ostream os)
{os \n title \n\t;for (int ix 0; ix vec.size(); ix)os vec[ix] ;os endl;
}
输出
0和138都是非法输入
sorry. Invalid position: 0Pentagonal Numeric Series1 5 12 22 35 51 70 92Pentagonal Numeric Series1 5 12 22 35 51 70 92 117 145 176 210 247 287
sorry. Invalid position: 138Process returned 0 (0x0) execution time : 0.029 s
Press any key to continue.
2.4
要求 写一个函数以静态局部(local static)的vector储存 Pentagonal 数列元素。 此函数返回一个 const 指针指向该 vector。 如果 vector 的大小小于指定的元素个数就扩充 vector 的大小。 接下来再实现第二个函数接受一个位置值返回该位置上的元素。 最后编写 main() 函数测试这些函数。 解释 1 // 第18行
return _elems; 在函数 pentagonal_series 中返回 _elems 的地址即指针是为了避免将整个 _elems 向量复制一次。通过返回指针可以避免内存的额外开销同时保证返回的是对同一个 _elems 向量的引用。 因为 _elems 是一个静态向量static vector它在函数第一次调用时被初始化并且在后续的调用中保持着其状态。如果不使用指针返回 _elems而是直接返回 _elems 本身那么每次函数调用时都会复制一份 _elems 向量这样会产生额外的开销和内存消耗。 因此通过返回指向 _elems 向量的指针可以有效地避免不必要的复制操作和内存开销。 代码
#includevector
#includeiostream // 输入输出流
using namespace std; // 标准命名空间// 检查输入是否有效
inline bool check_validity(int pos)
{return (pos 0 || pos 64) ? false : true;
}// 生成和返回数列
const vectorint* pentagonal_series(int pos)
{static vectorint _elems; // 数列的静态向量if (check_validity(pos) (pos _elems.size())) // 该位置未计算for (int ix _elems.size() 1; ix pos; ix)_elems.push_back( ix * (3*ix-1) / 2);return _elems; // 返回数列的指针
}// 获取指定位置的值
bool pentagonal_elem(int pos, int elem)
{if (!check_validity(pos)) { // 无效输入coutSorry. Invalid position: posendl;elem 0; // 元素置0return false;}const vectorint *pent pentagonal_series(pos); // 获取数列的指针elem (*pent)[pos - 1]; // 指定位置元素值return true;
}int main()
{int elem;if (pentagonal_elem(8, elem)) // 计算并输出位置 8 的值coutelement 8 is elem\n;if (pentagonal_elem(88, elem))coutelement 88 is elem\n;if (pentagonal_elem(12, elem))coutelement 12 is elem\n;if (pentagonal_elem(64, elem))coutelement 64 is elem\n;
}输出
element 8 is 92
Sorry. Invalid position: 88
element 12 is 210
element 64 is 61122.5
2.6会用模板再实现一次
要求 实现一个重载的 max() 函数接受以下参数 (a) 两个整数 (b) 两个浮点数 (c) 两个字符串 - - - - (d) 一个整数vector (e) 一个浮点数vector (f) 一个字符串vector - - - - (g) 一个整数数组 和 一个表示数组大小的整数值 (h) 一个浮点数数组 和 数组大小的整数值 (i) 一个字符串数组 和 数组大小的值 解释 1 inline string max(const string t1, const string t2) a. 常量引用 const string。这是因为字符串类型 string 的对象通常比较大如果不使用引用传递的话每次传递字符串时都会进行一次拷贝操作这样会增加额外的开销和内存消耗. b. 使用常量引用作为函数参数可以避免进行不必要的拷贝操作。常量引用允许我们在函数中以只读方式访问传递进来的字符串对象而无需复制整个对象 2 这些函数被声明为 inline以允许编译器将其插入到程序中的调用点从而提高性能 代码
#includeiostream
#includestring
#includealgorithm
#includevectorusing namespace std;inline int max(int t1, int t2){ return t1 t2 ? t1 : t2; }inline float max(float t1, float t2){ return t1 t2 ? t1 : t2; }// 常量引用
inline string max(const string t1, const string t2){ return t1 t2 ? t1 : t2; }// -------------------------------------// 常量引用...
inline int max(const vectorint vec){ return *max_element(vec.begin(), vec.end()); }inline float max(const vectorfloat vec){ return *max_element(vec.begin(), vec.end()); }inline string max(const vectorstring vec){ return *max_element(vec.begin(), vec.end()); }// -------------------------------------inline int max(const int *parray, int Size){ return *max_element(parray, parray Size); }inline float max(const float *parray, int Size){ return *max_element(parray, parray Size); }inline string max(const string *parray, int Size){ return *max_element(parray, parray Size); }int main()
{string sarray[] {we, were, her, pride, of, ten};vectorstring svec(sarray, sarray 6);int iarray[] {12,70,2,169,1,5,29};vectorint ivec(iarray, iarray 7);float farray[] {2.5, 24.8, 18.7, 4.1, 23.9};vectorfloat fvec(farray, farray 5);int imax max( max(ivec), max(iarray, 7) );float fmax max( max(fvec), max( farray, 5) );string smax max ( max(svec), max(sarray, 6) );cout imax should be 169 -- found: imax \n fmax should be 24.8 -- found: fmax \n smax should be were -- found: smax \n;return 0;
}输出
imax should be 169 -- found: 169
fmax should be 24.8 -- found: 24.8
smax should be were -- found: were
2.6
要求 以 template 重新完成练习 2.5并对 main() 函数适度修改。 用一个 template max() 函数取代 9 个 non-template max() 函数。 main() 不需要任何修改。 解释 1如果函数名还是 max会报错 2error: call of overloaded max(int, int) is ambiguous 3二义性错误的原因是使用了自定义的 max 函数与 algorithm 标准库中的 std::max 函数冲突 4这里将上个代码中的 max 改为 Max 即可 代码
#includeiostream
#includestring
#includealgorithm
#includevectorusing namespace std;template typename Type
inline Type Max(Type t1, Type t2){ return t1 t2 ? t1 : t2; };template typename elemType
inline elemType Max( const vectorelemType vec){ return *max_element( vec.begin(), vec.end() ); }template typename arrayType
inline arrayType Max( const arrayType *parray, int Size){ return *max_element( parray, parray Size ); }int main()
{string sarray[] {we, were, her, pride, of, ten};vectorstring svec(sarray, sarray 6);int iarray[] {12,70,2,169,1,5,29};vectorint ivec(iarray, iarray 7);float farray[] {2.5, 24.8, 18.7, 4.1, 23.9};vectorfloat fvec(farray, farray 5);int imax Max( Max(ivec), Max(iarray, 7) );float fmax Max( Max(fvec), Max( farray, 5) );string smax Max ( Max(svec), Max(sarray, 6) );cout imax should be 169 -- found: imax \n fmax should be 24.8 -- found: fmax \n smax should be were -- found: smax \n;return 0;
}输出
imax should be 169 -- found: 169
fmax should be 24.8 -- found: 24.8
smax should be were -- found: were
泛型编程风格 -- 第3章
3.1
要求 写一个读取文本文件的程序将文件中的每个 key 存入map 再定义一个由 “排除字眼” 组成的 set其中包含 a, an, or , the, but 之类的 Key 将某个 key 放入 map 前先确定该 key 不在 “排除字集” 中 一旦文本读取完毕显示一份 key 清单并显示每个 key 出现次数 还可加以扩展显示 key 前允许用户查询某个 Key 是否出现在文本文件中 解释 1const setstring 为啥后面加个 答 在C中函数可以使用引用参数Reference Parameter。在函数声明中在参数类型后面加上符号就表示该参数是一个引用类型的参数。 const setstring exclude_set 这里的exclude_set是一个常量引用它指向一个setstring对象。使用引用参数的好处是避免了函数调用时进行大量的拷贝操作提高了程序的性能和效率。通过使用引用参数函数可以直接访问和修改传递给它的实际对象而无需创建对象的副本。 另外在这个示例代码中将exclude_set声明为常量引用的原因是函数initialize_exclusion_set只需要读取exclude_set而不会修改它的内容。通过将其声明为常量引用可以确保函数内部不会意外地修改exclude_set 2 ifstream ifile(C:\\Users\\1\\Desktop\\C\\column.txt);
ofstream ofile(C:\\Users\\1\\Desktop\\C\\column.map); 答 定义了两个文件流ifstream和ofstream其中ifile打开了名为C:\My Documents\column.txt的文本文件而ofile则打开了名为C:\My Documents\column.map的二进制文件。可以通过这些文件流来读取或写入文件中的内容 3 cerr Unable to open file -- bailing out!\n; 答 a. cerr是C标准库中的一个输出流对象它代表了标准错误流standard error stream。与cout用于标准输出不同cerr主要用于将错误消息输出到终端或其他错误日志文件中。 b. 是C中的流插入运算符用于将字符串或其他数据插入到输出流中 c. cerr可以将错误信息输出到标准错误流中而不是标准输出流cout中。这样做有助于区分程序的正常输出和错误信息方便调试和错误处理 4 mapstring, int::const_iterator it; 答 声明了一个名为 it 的常量迭代器iterator用于遍历 mapstring, int 容器中的元素 迭代器 迭代器将容器和算法联系起来。 在 C 标准库中很多算法函数如排序、查找、遍历等都接受迭代器作为参数。这些算法函数不依赖于具体的容器类型而是通过迭代器来遍历和处理容器中的元素从而实现对容器的各种操作。 column.txt
MooCat is a long-haired white kitten with large
black patches Like a cow looks only he is a kitty
poor kitty Alice says cradling MooCat in her arms
pretending he is not struggling to break free
代码
#includemap // 包含map库用于使用映射容器
#includeset // 包含set库用于使用集合容器
#includestring // 包含string库用于使用字符串
#includeiostream // 包含iostream库用于输入输出操作
#includefstream // 包含fstream库用于文件操作
using namespace std;void initialize_exclusion_set(setstring); // 初始化排除词集合
void process_file(mapstring, int, const setstring, ifstream); // 处理文件统计单词出现次数
void user_query(const mapstring, int); // 用户查询查找指定单词的出现次数
void display_word_count(const mapstring, int, ofstream); // 显示单词及其出现次数int main()
{ifstream ifile(C:\\Users\\1\\Desktop\\C\\column.txt); // 打开输入文件流读取文件ofstream ofile(C:\\Users\\1\\Desktop\\C\\column.map); // 打开输出文件流写入文件if (!ifile || !ofile) {cerr Unable to open file -- bailing out!\n; // 若打开文件失败输出错误信息并退出程序return -1;}setstring exclude_set; // 定义排除词集合initialize_exclusion_set(exclude_set); // 初始化排除词集合mapstring, int word_count; // 定义单词计数映射容器process_file(word_count, exclude_set, ifile); // 处理文件统计单词出现次数user_query(word_count); // 用户查询查找指定单词的出现次数display_word_count(word_count, ofile); // 显示单词及其出现次数return 0;
}void initialize_exclusion_set(setstring exs) {static string _excluded_words[25] {the, and, but, that, then, are, been,can, a, could, did, for, of,had, have, him, his, her, its, is,were, which, when, with, would};exs.insert(_excluded_words, _excluded_words 25); // 将排除词插入排除词集合中
}void process_file(mapstring, int word_count,const setstring exclude_set, ifstream ifile)
{string word;while (ifile word) {if (exclude_set.count(word))continue; // 若单词在排除词集合中则跳过该单词继续下一次循环word_count[word]; // 统计单词出现次数}
}void user_query(const mapstring, int word_map)
{string search_word;cout Please enter a word to search: q to quit ;cin search_word;while (search_word.size() search_word ! q) {mapstring, int::const_iterator it;if ((it word_map.find(search_word)) ! word_map.end())cout Found! it-first occurs it-second times.\n; // 输出找到的单词及其出现次数else cout search_word was not found in text.\n; // 输出未找到的单词信息cout \nAnother search? (q to quit) ;cin search_word;}
}void display_word_count(const mapstring, int word_map, ofstream os)
{mapstring, int::const_iteratoriter word_map.begin(),end_it word_map.end();while (iter ! end_it) {os iter-first ( iter-second ) endl; // 输出单词及其出现次数到输出文件流iter;}os endl;
}输出
Please enter a word to search: q to quit Alice
Found! Alice occurs 1 times.Another search? (q to quit) MooCat
Found! MooCat occurs 2 times.Another search? (q to quit) a
a was not found in text.Another search? (q to quit) q
3.4
前言
1 关于back_inserter()back_inserter的使用-CSDN博客
2关于 partition()
std::partition - cppreference.com
c11std::partition-CSDN博客
3关于 copy()cplusplus.com/reference/algorithm/copy/
4关于 eos eos是一个标识迭代器它表示输入数据的结束位置。在这段代码中istream_iteratorint eos;声明了一个名为eos的istream_iterator对象用于指示输入数据的结束。 通过使用copy(in, eos, back_inserter(input));将输入流in中的数据复制到整数型向量input中。copy函数会从in开始读取数据直到遇到eos即输入数据的结束位置。 因此eos在这里起到了标记输入数据结束位置的作用它是一个特殊的迭代器不指向实际的数据只是表示输入结束的标志 要求 编写一个程序利用 istream_iterator 从标准输入设备读取一连串整数。 利用 ostream_iterator 将其中的奇数写至某个文件每个数值皆以空格分隔。 再利用 ostream_iterator 将偶数写到另一个文件每个数值单独放在一行中。 首先定义2个 istream_iterator用来从标准输入设备读入一串整数。其中一个绑定(bind)至 cin另一个表示文件结束 (end-of-file)
istream_iteratorint in( cin ), eos;
接下来定义一个 vector用来存储读入的元素
vector int input;
以下使用泛型算法 copy() 进行读取操作
#include iterator
#include vector
#include iostream
#include algorithm
using namespace std;int main()
{vector int input;istream_iteratorint in( cin ), eos;copy( in, eos, back_inserter( input ));// ...
}
在此vector 是必要的因为 copy() 会采用 assignment 运算符来复制每个元素。由于 input vector 是空的第一个元素赋值操作就会导致溢出overfolw错误。使用 back_iterator() 可以避免 assignment 运算符改以 push_back() 函数来插入函数。
下面以泛型算法 partition() 来区分奇偶数。当然还得配合 function object even_elem() 的使用后者在传入值为偶数时会返回 true
class even_elem {
public:bool operator() ( int elem ){ return elem % 2 ? false : true; }
};vectorint::iterator division partition( input.begin(), input.end(), even_elem() );
还需要 2 个 ostream_iterator一个用于偶数文件一个用于奇数文件。
首先以 ofstream class 打开两个输出文件
#includefstream
ofstream even_file( C:\\Users\\1\\Desktop\\C\\even_file ),odd_file( C:\\Users\\1\\Desktop\\C\\odd_file );if ( !even_file || !odd_file) {cerr arghh! unable to open the output files. bailing out!;return -1;
}
再将这 2 个 ostream_iterator 绑定至相应的 ofstream 对象上。第 2 个参数代表每个元素输出时的分隔符。
ostream_iteratorint even_iter( even_file, \n ),odd_iter( odd_file, );
最后再以泛型算法 copy()将已被分开的奇偶元素分别输出至不同文件
copy( input.begin(), division, even_iter );
copy( division, input.end(), odd_iter );
完整代码
#include iterator // 包含迭代器相关的头文件
#include vector // 包含向量容器的头文件
#include iostream // 包含输入输出流的头文件
#include algorithm // 包含标准算法的头文件
#include fstream // 包含文件流的头文件
using namespace std; // 使用标准命名空间class even_elem { // 定义一个名为even_elem的类
public:bool operator()(int elem) // 重载()运算符用于判断是否为偶数{return elem % 2 ? false : true; // 奇数返回 false}
};int main()
{vectorint input; // 创建一个整型向量input用于存储输入的数据istream_iteratorint in(cin), eos; // 创建一个istream_iterator对象in用于从cin读取数据copy(in, eos, back_inserter(input)); // 将输入的数据复制到input向量中// 使用partition函数将input向量中的元素按照even_elem对象进行分割并返回分割点的迭代器vectorint::iterator division partition(input.begin(), input.end(), even_elem()); ofstream even_file(C:\\Users\\1\\Desktop\\C\\even_file), // 打开一个名为even_file的输出文件流odd_file(C:\\Users\\1\\Desktop\\C\\odd_file); // 打开一个名为odd_file的输出文件流if (!even_file || !odd_file) { // 检查是否成功打开了输出文件流如果失败则输出错误信息并返回-1cerr arghh! unable to open the output files. bailing out!;return -1;}ostream_iteratorint even_iter(even_file, \n), // 创建一个ostream_iterator对象even_iter用于向even_file写入数据并以换行符分隔odd_iter(odd_file, ); // 创建一个ostream_iterator对象odd_iter用于向odd_file写入数据并以空格分隔copy(input.begin(), division, even_iter); // 将input向量中的偶数部分复制到even_iter指定的输出流中copy(division, input.end(), odd_iter); // 将input向量中的奇数部分复制到odd_iter指定的输出流中
}
输入输出
然后到创建好的文件查看就行
2 4 5 3 9 5 2 6 8 1 8 4 5 7 3 520 1314^Z