如何使用 istream_iterators 拆分等式?
how to use istream_iterators to split an equation?
我试图将像 ( 1 + 2 )
这样的字符串拆分成一个向量,当使用 istream_iterators<string>
时它不会拆分括号所以我得到像
这样的向量输出
(1 , + , 2)
当我想要 ( , 1, + , 2 ,)
是否可以使用 istream_iterator
s 来实现这一点?
string eq = "(1 + 2)";
istringstream ss(eq);
istream_iterator<string> begin(ss);
istream_iterator<string> end;
vector<string> vec(begin, end);
我认为您无法使用 istream_iterator
来完成。相反,只需手动完成:
vector<string> vec;
vec.reserve(eq.size() / 4); // rough guess
bool in_number = false;
for (char ch : eq) {
if (isspace(ch)) {
in_number = false;
} else if (isdigit(ch)) {
if (in_number) {
vec.back().push_back(ch);
} else {
vec.emplace_back(1, ch);
in_number = true;
}
} else {
vec.emplace_back(1, ch);
in_number = false;
}
}
您可以通过创建自定义类型 Token
并将其与
istream_iterator
。额外功能:此代码将解析多个数字、多个运算符和嵌套表达式。所以享受吧。 :)
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <cctype>
using namespace std;
class Token {
private:
string val;
public:
Token() : val("") {}
Token(string& v) : val(v) {}
friend istream& operator>>(istream &in, Token& tok);
friend ostream& operator<<(ostream &out, Token& tok);
};
istream& operator>>(istream &in, Token& tok) {
char c;
string v;
if (in >> c) {
if (isdigit(c)) {
v.push_back(c);
while (in >> c && isdigit(c)) {
v.push_back(c);
}
in.putback(c);
} else if (c == ' ') {
while (in >> c && c == ' ') ;
in.putback(c);
} else {
v.push_back(c);
}
}
tok = v;
return in;
}
ostream& operator<<(ostream &out, Token& tok) {
out << tok.val;
return out;
}
int main() {
string eq = "(1 + 2)";
//eq = "(100 + 200)"; // multiple digits
//eq = "(100 + 200 * 300)"; // extra operator
//eq = "(100 + (200 * 300))"; // nested parens
istringstream ss(eq);
istream_iterator<Token> begin(ss);
istream_iterator<Token> end;
vector<Token> vec(begin, end);
for (auto& x : vec) {
cout << "[" << x << "] ";
}
cout << endl;
}
我试图将像 ( 1 + 2 )
这样的字符串拆分成一个向量,当使用 istream_iterators<string>
时它不会拆分括号所以我得到像
(1 , + , 2)
当我想要 ( , 1, + , 2 ,)
是否可以使用 istream_iterator
s 来实现这一点?
string eq = "(1 + 2)";
istringstream ss(eq);
istream_iterator<string> begin(ss);
istream_iterator<string> end;
vector<string> vec(begin, end);
我认为您无法使用 istream_iterator
来完成。相反,只需手动完成:
vector<string> vec;
vec.reserve(eq.size() / 4); // rough guess
bool in_number = false;
for (char ch : eq) {
if (isspace(ch)) {
in_number = false;
} else if (isdigit(ch)) {
if (in_number) {
vec.back().push_back(ch);
} else {
vec.emplace_back(1, ch);
in_number = true;
}
} else {
vec.emplace_back(1, ch);
in_number = false;
}
}
您可以通过创建自定义类型 Token
并将其与
istream_iterator
。额外功能:此代码将解析多个数字、多个运算符和嵌套表达式。所以享受吧。 :)
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <cctype>
using namespace std;
class Token {
private:
string val;
public:
Token() : val("") {}
Token(string& v) : val(v) {}
friend istream& operator>>(istream &in, Token& tok);
friend ostream& operator<<(ostream &out, Token& tok);
};
istream& operator>>(istream &in, Token& tok) {
char c;
string v;
if (in >> c) {
if (isdigit(c)) {
v.push_back(c);
while (in >> c && isdigit(c)) {
v.push_back(c);
}
in.putback(c);
} else if (c == ' ') {
while (in >> c && c == ' ') ;
in.putback(c);
} else {
v.push_back(c);
}
}
tok = v;
return in;
}
ostream& operator<<(ostream &out, Token& tok) {
out << tok.val;
return out;
}
int main() {
string eq = "(1 + 2)";
//eq = "(100 + 200)"; // multiple digits
//eq = "(100 + 200 * 300)"; // extra operator
//eq = "(100 + (200 * 300))"; // nested parens
istringstream ss(eq);
istream_iterator<Token> begin(ss);
istream_iterator<Token> end;
vector<Token> vec(begin, end);
for (auto& x : vec) {
cout << "[" << x << "] ";
}
cout << endl;
}