我有一个数据文件是由一系列嵌套系列组成的单行,例如。
[[0.127279,0.763675,0.636396],[0.254558,0.890955,0.636396],
[0.127279,0.636396,0.763675],[0.254558,0.763675,0.763675],
[0.381838,0.890955,0.763675],[0.127279,0.509117,0.890955],
[0.254558,0.636396,0.890955],[0.509117,0.890955,0.890955]]
我希望能够使用流操作符将其读入STL vector<vector<double> >
,该操作符模仿内部类型A:
vector<vector<double> > A;
FIN >> A;
当矢量未嵌套时,我已经想出了一种方法,即。一个简单的vector<T>
如下:
template <class T>
istream& operator>>(istream& s, vector<T> &A){
T x;
string token; char blank;
s >> blank; // Gobble the first '['
while( getline(s, token, ',') ) {
istringstream input(token);
input >> x;
A.push_back(x);
}
s >> blank; // Gobble the last ']'
return s;
}
但我对istream& operator>>(istream& s, vector<vector<T> >&A)
部分有疑问,因为我似乎无法正确捕捉内部]
。我确信Boost有办法做到这一点,但我希望看到STL的解决方案用于教学目的。
注意:我知道重载vector<T>
的流操作符可能会产生深远的不良后果,并且实现应该包含在它自己的类中 - 我正在使用上面的这个例子澄清这个问题。
修改 我希望这个方法足够健壮,能够处理一个输入数组,该数组的大小(和内部数组)大小事先已知 ,但是从读取流中推断出来。
答案 0 :(得分:2)
实际上,当T
为vector<double>
时,您希望对两者使用相同功能的代码存在问题:
double
T
但需要将数据读入 vector 和 double 的逻辑略有不同。所以你不能这样做,至少不是那么简单的逻辑:
我更愿意编写两个函数,分别处理两个案例。毕竟,即使在您的情况下,编译器也会为template <class T>
istream& operator>>(istream& s, vector<T> &A)
{
T x;
string token; char blank;
s >> blank; // Gobble the first '['
while( getline(s, token, ',') )
{
istringstream input(token);
input >> x;
A.push_back(x);
}
// s >> blank; // Gobble the last ']'
return s;
}
template <class T>
istream& operator>>(istream& s, vector<vector<T>> &A)
{
vector<T> x;
string token;
char blank;
s >> blank; // Gobble the first '['
while( getline(s, token, ']') )
{
istringstream input(token);
input >> x;
s >> blank; //read , after [...]
A.push_back(x);
x.clear();
}
s >> blank; // Gobble the last ']'
return s;
}
的每个值生成两个不同的函数。
int main() {
vector<vector<double>> A;
cin >> A;
for(size_t i = 0 ;i < A.size(); ++i)
{
for(size_t j = 0 ; j < A[i].size(); ++j)
cout << A[i][j] <<" ";
cout << endl;
}
return 0;
}
测试代码:
[[1,2,3],[4,5,6],
[7,8,9],[10,11,12],
[13,14,15],[16,17,18],
[19,20,21],[22,23,24]]
输入:
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
19 20 21
22 23 24
输出:
{{1}}
答案 1 :(得分:1)
在您的特定示例中非常简单。
现在你可以有一个简单的循环
double x;
while( stringstreamp >> x )
{
}
读取三个双精度后的一些特殊逻辑将它们插入到一个新数组中。
答案 2 :(得分:1)
几年后,我在这里遇到同样的问题。
根据您的贡献,我开发了原始模板的修改版本。这个可以解析多维数组,即使它们分布在多行上。
template <class T>
istream& operator>>(istream& s, vector<T> &A){
while(true){
T x;
char c = s.peek();
if( c == '[' || c == ','){
s.ignore();
if(s >> x) A.push_back(x);
else throw invalid_argument("Bad, bad JS array!");
continue;
}
if( c == ']') {
s.ignore();
return s;
}
/* Ignore line-break */
s.ignore();
}
return s;
}
希望这对某人有用。