简单的 C++ 分词器
Simple C++ tokenizer
我正在为 HackerRank 上的挑战编写程序,我需要解析 HRML,一种类似于 HTML:
的标记语言
<tag1 value = "Hello World"></tag1>
作为程序的一部分,我有一个函数应该用字符串标记填充字符串向量。它适用于标签,但我还需要标记查询,格式如下:
tag1.tag2.tag3~attribute_name
该函数的行为类似于字符串迭代器在遇到波浪号后停止前进。
这是代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void tokenize_string(vector<string>& vector, string str)
{
string current_token;
for (auto i = str.begin(); i != str.end(); i++)
{
if (isalnum(*i))
{
current_token += *i;
}
else
{
//We extracted a token
vector.push_back(current_token);
current_token = "";
}
}
//Remove empty strings that the previous loop placed into the vector
for (auto i = vector.begin(); i != vector.end(); i++)
{
if (*i == "")
{
vector.erase(i);
i = vector.begin();
}
}
}
int main()
{
//A simple test
vector<string> tag_tokens;
vector<string> query_tokens;
tokenize_string(tag_tokens, "<tag1 name=\"Hello\">");
tokenize_string(query_tokens, "tag1.tag2.tag3~name");
for (auto it = tag_tokens.begin(); it != tag_tokens.end(); it++)
{
cout << *it << ' ';
}
cout << '\n';
for (auto it = query_tokens.begin(); it != query_tokens.end(); it++)
{
cout << *it << ' ';
}
cout << '\n';
cin.get();
return 0;
}
这是因为你没有考虑到达输入字符串末尾后的最后一个标记
i != str.end()
.
在 for 循环之后添加 vector.push_back(current_token);
以考虑最后一个标记。
void tokenize_string(vector<string>& vector, string str)
{
string current_token;
for (auto i = str.begin(); i != str.end(); i++)
{
if (isalnum(*i))
{
current_token += *i;
}
else
{
//We extracted a token
vector.push_back(current_token);
current_token = "";
}
}
vector.push_back(current_token); ///-------->pushes last token
//Remove empty strings that the previous loop placed into the vector
for (auto i = vector.begin(); i != vector.end(); i++)
{
if (*i == "")
{
vector.erase(i);
i = vector.begin();
}
}
}
这是一种需要更少代码行的不同方法:
void tokenize_string(
std::vector< std::string >& output,
const std::string& csv,
const string& delimiters )
{
for( char del : delimiters ) {
std::stringstream sst(csv);
std::string a;
while( getline( sst, a, del) )
output.push_back(a);
}
}
我正在为 HackerRank 上的挑战编写程序,我需要解析 HRML,一种类似于 HTML:
的标记语言<tag1 value = "Hello World"></tag1>
作为程序的一部分,我有一个函数应该用字符串标记填充字符串向量。它适用于标签,但我还需要标记查询,格式如下:
tag1.tag2.tag3~attribute_name
该函数的行为类似于字符串迭代器在遇到波浪号后停止前进。 这是代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void tokenize_string(vector<string>& vector, string str)
{
string current_token;
for (auto i = str.begin(); i != str.end(); i++)
{
if (isalnum(*i))
{
current_token += *i;
}
else
{
//We extracted a token
vector.push_back(current_token);
current_token = "";
}
}
//Remove empty strings that the previous loop placed into the vector
for (auto i = vector.begin(); i != vector.end(); i++)
{
if (*i == "")
{
vector.erase(i);
i = vector.begin();
}
}
}
int main()
{
//A simple test
vector<string> tag_tokens;
vector<string> query_tokens;
tokenize_string(tag_tokens, "<tag1 name=\"Hello\">");
tokenize_string(query_tokens, "tag1.tag2.tag3~name");
for (auto it = tag_tokens.begin(); it != tag_tokens.end(); it++)
{
cout << *it << ' ';
}
cout << '\n';
for (auto it = query_tokens.begin(); it != query_tokens.end(); it++)
{
cout << *it << ' ';
}
cout << '\n';
cin.get();
return 0;
}
这是因为你没有考虑到达输入字符串末尾后的最后一个标记
i != str.end()
.
在 for 循环之后添加 vector.push_back(current_token);
以考虑最后一个标记。
void tokenize_string(vector<string>& vector, string str)
{
string current_token;
for (auto i = str.begin(); i != str.end(); i++)
{
if (isalnum(*i))
{
current_token += *i;
}
else
{
//We extracted a token
vector.push_back(current_token);
current_token = "";
}
}
vector.push_back(current_token); ///-------->pushes last token
//Remove empty strings that the previous loop placed into the vector
for (auto i = vector.begin(); i != vector.end(); i++)
{
if (*i == "")
{
vector.erase(i);
i = vector.begin();
}
}
}
这是一种需要更少代码行的不同方法:
void tokenize_string(
std::vector< std::string >& output,
const std::string& csv,
const string& delimiters )
{
for( char del : delimiters ) {
std::stringstream sst(csv);
std::string a;
while( getline( sst, a, del) )
output.push_back(a);
}
}