我们能否通过返回类型vector的功能来初始化c ++中的vector。
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) {
// Complete this function
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str); /** here is the problem **/
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}
答案 0 :(得分:0)
是的,可以从函数返回std::vector
。这样一来,就像您所说的那样,“用向量初始化向量”。在C ++中,我们可以利用RVO,即返回值优化。您可以阅读here有关复制省略和RVO的信息。基本上说,从函数返回值的容器时,复制字节不会有问题。现在甚至是推荐的方法。
因此,您可以(并且应该)从函数返回std::vector
。编译器会注意这以优化的方式工作。
但是首先,请参见以下示例:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
std::vector<int> parseInts(std::string str) {
// Put the string into a stream
std::istringstream iss{ str };
// Return the vector of ints
return { std::istream_iterator<int>(iss), {} };
}
int main() {
// Test data
std::string test{ "1 2 3 4 5 6 7 8 9 10" };
// Get the vector with the ints
std::vector ints = parseInts(test);
// Show output
for (const int i : ints)
std::cout << i << "\n";
return 0;
}
我们有一个名为parseInts
的函数,仅包含两行代码。
首先,我们将字符串放入istringstream中。这样,就有可能像
一样从新流中提取int。std::istringstream iss{ str };
int i1, i2;
iss >> i1 >> i2;
提取器运算符>>将从流(字符串)中“提取”空格分隔的整数值。
但是,如果我们看一下,就会发现,我们需要知道字符串中整数的数量,然后重复写入“ >>”。为了重复处理相同数量的项(例如整数),我们在C ++中提供了迭代器。使用迭代器,您可以遍历容器中的相似元素。如果您假设字符串为容器,则当然可以遍历其中的整数。有可用的迭代器可以为我们完成此任务。
对于流,我们有std::istream_iterator。这个东西将遍历输入流中某种类型的所有以空格分隔的项目,并返回值。
此迭代器返回的许多值最好存储在std::vector
中,因为它是一个动态增长的容器。对我们来说很理想,因为我们不预先知道流中的整数数量。
如果我们查看std::vector
,就会发现它具有所谓的范围构造函数。请在此处查看:range constructor (number 5)。
使用范围构造函数,我们定义了std::vector
类型的变量,并使用“ begin”和“ end”迭代器对其进行了初始化。此范围内的值将被放入向量中。
如果在示例中定义类型为std::vector
的变量,我们可以编写:
std::vector<int> intv{ std::istream_iterator<int>(iss), std::istream_iterator<int>() };
或
std::vector<int> intv( (std::istream_iterator<int>(iss)), std::istream_iterator<int>() );
请不要在第一个参数中使用大括号。这对于防止最棘手的解析问题很有必要。您不想定义一个函数,而是一个变量。
但是我们还是不会使用它。因为具有统一的初始化,并且{} -initializer为默认初始化器。我们可以使用默认的2nd参数。现在我们可以写:
std::vector<int> intv(std::istream_iterator<int>(iss), {});
因此,接下来,我们可以使用CTAD Class template argument deduction。基本上,编译器从构造函数中的参数知道它将构造容器的哪种数据类型。因此,无需编写它。
现在:
std::vector intv(std::istream_iterator<int>(iss), {});
这看起来已经非常不错了,您现在可以返回变量intv。
但是还有更多。编译器知道函数的类型以及应该返回什么。因此,您可以使用支撑的初始化程序并将其返回,并且编译器知道您要返回std::vector<int>
最后的声明是:
return { std::istream_iterator<int>(iss), {} };
我希望这会有所帮助。
对于一行代码的详细说明,我们深表歉意。
答案 1 :(得分:-3)
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) { //this line tells that function will return an integer vector
vector <int> hello;
int n,ele;
cout<<"Enter An Integer:";
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ele;
hello.push_back(ele);
}
return hello; //vector named hello returned to main function
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str); /** here is the problem **/
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}
希望这会有所帮助
答案 2 :(得分:-3)
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
vector<int> parseInts(string str) {
vector <int> hello;
int n,ele;
stringstream geek(str); // object from the class stringstream
geek>>n; //converts to int
for(int i=0;i<n;i++)
{
cin>>ele;
hello.push_back(ele);
}
return hello;
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str); /** here is the problem **/
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
system("pause");
return 0;
}