我寫了這個拆分函式,找不到按 string_view(幾個字符)拆分的簡單方法。我的功能:
size_t split(std::vector<std::string_view>& result, std::string_view in, char sep) {
result.reserve(std::count(in.begin(), in.end(), in.find(sep) != std::string::npos) 1);
for (auto pfirst = in.begin();; pfirst) {
auto pbefore = pfirst;
pfirst = std::find(pfirst, in.end(), sep);
result.emplace_back(q, pfirst-pbefore);
if (pfirst == in.end())
return result.size();
}
}
我想用 string_view 分隔符呼叫這個拆分函式。例如:
str = "apple, phone, bread\n keyboard, computer"
split(result, str, "\n,")
Result:['apple', 'phone', 'bread', 'keyboard', 'computer']
我的問題是,我怎樣才能盡快實作這個功能?
uj5u.com熱心網友回復:
首先,你使用std::count()不當。
其次,std::string_view有它自己的find_first_of()和substr()方法,你可以在這種情況下使用它,而不是使用迭代器。 find_first_of()允許您指定要搜索的多個字符。
嘗試更像這樣的事情:
size_t split(std::vector<std::string_view>& result, std::string_view in, std::string_view seps) {
result.reserve(std::count_if(in.begin(), in.end(), [&](char ch){ return seps.find(ch) != std::string_view::npos; }) 1);
std::string_view::size_type start = 0, end;
while ((end = in.find_first_of(seps, start)) != std::string_view::npos) {
result.push_back(in.substr(start, end-start));
start = in.find_first_not_of(' ', end 1);
}
if (start != std::string_view::npos)
result.push_back(in.substr(start));
return result.size();
}
在線演示
uj5u.com熱心網友回復:
這是我對拆分字串視圖的看法,只需在字串視圖中的所有字符上回圈一次并回傳一個 string_views 向量(因此不復制資料)呼叫代碼仍然可以使用 words.size() 來獲取大小,如果需要。(我使用 C 20 std::set contains 函式)
現場演示:https : //onlinegdb.com/tHfPIeo1iM
#include <iostream>
#include <set>
#include <string_view>
#include <vector>
auto split(const std::string_view& string, const std::set<char>& separators)
{
std::vector<std::string_view> words;
auto word_begin{ string.data() };
std::size_t word_len{ 0ul };
for (const auto& c : string)
{
if (!separators.contains(c))
{
word_len ;
}
else
{
// we found a word and not a seperator repeat
if (word_len > 0)
{
words.emplace_back(word_begin, word_len);
word_begin = word_len;
word_len = 0;
}
word_begin ;
}
}
// string_view doesn't have a trailing zero so
// also no trailing separator so if there is still
// a word in the "pipeline" add it too
if (word_len > 0)
{
words.emplace_back(word_begin, word_len);
}
return words;
}
int main()
{
std::set<char> seperators{ ' ', ',', '.', '!', '\n' };
auto words = split("apple, phone, bread\n keyboard, computer", seperators);
bool comma = false;
std::cout << "[";
for (const auto& word : words)
{
if (comma) std::cout << ", ";
std::cout << word;
comma = true;
}
std::cout << "]\n";
return 0;
}
uj5u.com熱心網友回復:
我不知道性能,但這段代碼似乎簡單多了
std::vector<std::string> ParseDelimited(
const std::string &l, char delim )
{
std::vector<std::string> token;
std::stringstream sst(l);
std::string a;
while (getline(sst, a, delim))
token.push_back(a);
return token;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/382473.html
標籤:C
下一篇:如何旋轉四邊形
