赞
踩
Contents
std::copy 简介
使用std::copy把文件中的内容放入vector中
case1:把文件中的单词直接放到一个vector中
case2:把文件中的数值放到一个vector中
使用std::copy把cin中的东西直接放到vector中
使用std::copy把vector中的值直接打印出来(输出到std::cout)
使用std::copy直接打印出文件中的内容
函数原型:
- template<class InputIterator, class OutputIterator>
- OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
- {
- while (first!=last) {
- *result = *first;
- ++result; ++first;
- }
- return result;
- }
上面这是标准库里写的,可见其形式参数是两个输入迭代器和一个输出迭代器!这两个输入迭代器决定了我们要拷贝的范围,那个输出迭代器明确了我们要拷贝到哪里去!
但是有一点需要注意:我们需要保证目的容器的空间足够大以至于能放下拷贝过来的内容。如果你的目的容器是一个空的容器,那么可以使用back_inserter(container)
来创建一个插入迭代器作为输出迭代器!
case1:把文件中的单词直接放到一个vector中
这个功能有的时候也算是比较常用的吧,做一些统计之类的操作。比如我要把像下图中的这个文本中的所有单词放到一个vector中。
先上代码后解释
- std::vector<std::string> words;
- std::ifstream in_file("words.txt");
- std::copy(std::istream_iterator<std::string>(in_file),std::istream_iterator<std::string>(),std::back_inserter(words));
就这三行就能把文本中所有以空格分开的字符串都放到一个vector中如下:
传统的方式是用一个while循环来做的,一次读一行,对这一行的字符串按空白进行分割。这听起来就感觉挺麻烦的(所以我就不写代码了),肯定没有这种函数式的风格简洁。
上述代码需要如下的头文件
- #include<fstream> // for ifstream
- #include<iterator> // for istream_iterator and back_inserter
- #include<algorithm> // for copy
- #include<vector>
- #include<string>
- std::ifstream in_file("words.txt");
- 这个式用来创建一个(读)文件流,用于初始化后面的输入迭代器
- copy 的第一个参数:
- std::istream_iterator<std::string>(in_file),
-
- istream_iterator是一个输入流的迭代器;
- 它有一个模板参数,用于表示迭代器指向的类型;
- 我们这里是让迭代器指向文件中的一个单词,也就是一个string;
- 所以这个模板参数设置为std::string。
-
- 它接收一个参数表示是哪个流的迭代器,很明显这里应该是文件流的迭代器。
- copy的第二个参数:
- std::istream_iterator<std::string>()
- 这是一个尾后迭代器,不接收参数就表示一个尾后迭代器!
- copy的第三个参数:
- std::back_inserter(words);
-
- 这个back_inserter用来创建一个插入迭代器;
- 它接收一个容器对象作为参数;
- 实际上是在不断地调用这个容器的: push_back()方法;(前提是这个容器有push_back方法)
case2:把文件中的数值放到一个vector中
这个应用场景也挺多的,就拿我这专业上的例子来说:我通过采集信号的设备,采集信号,然后保存到文件里,方便后续的分析。那么我们读这个保存信号的文件也就能用这个方法!
如下图,我创建了一个存了若干个double的文件,我还是用三行代码把它放到一个vector中。代码和上面的代码几乎一样,只不过把模板参数类型由string换成double
代码和上面一样,就不解释了,把string换成double就行
- std::vector<double> sig;
- std::ifstream in_file("signals.txt");
- std::copy(std::istream_iterator<double>(in_file),std::istream_iterator<double>(),std::back_inserter(sig));
观察结果发现,其实这样做还是有点误差的,但是还是可以忽略不计的,差了10的-14次方。
这个这两天我用的比较多,最近一直在找工作,参加了一些公司的笔试,考算法题,这些算法题的输入都是从std::cin中获取。
如果是从命令行中输入单个变量的值就直接像下面这样就好:
- int a;
- std::cin >> a;
但是,如果,我要一下子输入多个相同类型的值呢?比如输入多个数字到一个vector中,传统的方法还是用while循环来干。但是你用std::copy的话,一行就行(除了定义变量)。
- std::vector<int> nums;
- std::copy(std::istream_iterator<int>(std::cin),std::istream_iterator<int>(),std::back_inserter(nums));
- std::vector<int> vec{1, 2, 3, 4, 5};
- std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\t\t"));
- 这里std::copy的第三个参数:
- std::ostream_iterator<int>(std::cout, "\t\t")
-
- 和前面的的istream_iterator不同的是,这里它还能制定一个分隔符;
- 这里以两个制表符来分隔vector中的每个元素。
- std::ifstream in_file("words.txt");
- std::copy(std::istream_iterator<std::string>(in_file),
- std::istream_iterator<std::string>(),
- std::ostream_iterator<std::string>(std::cout, " ")
- );
这个copy这块原本是一行的,但是太长了,就分开了。反正就是一个内置的算法函数。
怎么样?反正比 用while循环读 方便吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。