我想要一個按分隔符陣列拆分文本的函式。我有一個完美運行的演示,但它真的很慢。這是引數的示例。
文本:
“pop-pap-bab 鮑勃”
分隔符向量:
“-”,“”
結果:
“pop”、“-”、“pap”、“-”、“bab”、“bob”
因此,函式回圈拋出字串并嘗試查找分隔符,如果找到分隔符,則將找到的文本和分隔符推送到結果陣列,如果文本僅包含空格或為空,則不推送文本.
std::string replace(std::string str,std::string old,std::string new_str){
size_t pos = 0;
while ((pos = str.find(old)) != std::string::npos) {
str.replace(pos, old.length(), new_str);
}
return str;
}
std::vector<std::string> split_with_delimeter(std::string str,std::vector<std::string> delimeters){
std::vector<std::string> result;
std::string token;
int flag = 0;
for(int i=0;i<(int)str.size();i ){
for(int j=0;j<(int)delimeters.size();j ){
if(str.substr(i,delimeters.at(j).size()) == delimeters.at(j)){
if(token != ""){
result.push_back(token);
token = "";
}
if(replace(delimeters.at(j)," ","") != ""){
result.push_back(delimeters.at(j));
}
i = delimeters.at(j).size()-1;
flag = 1;
break;
}
}
if(flag == 0){token = str.at(i);}
flag = 0;
}
if(token != ""){
result.push_back(token);
}
return result;
}
我的問題是,函式真的很慢,因為它有 3 個回圈。我想知道是否有人知道如何使該功能更快。對不起,如果我不夠清楚,我的英語不是最好的。
uj5u.com熱心網友回復:
也許,作為替代方案,您可以使用正則運算式?但也許對你來說也太慢了。. .
使用正則運算式生活會非常簡單。
請看下面的例子:
#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <iterator>
const std::regex re(R"((\w |[\- ]))");
int main() {
std::string s{"pop-pap-bab bob"};
std::vector<std::string> part{std::sregex_token_iterator(s.begin(),s.end(),re),{}};
for (const std::string& p : part) std::cout << p << '\n';
}
我們將std::sregex_token_iterator與std::vectors 范圍建構式結合使用,以提取正則運算式中指定的所有內容,然后將所有這些內容放入std::vector
正則運算式本身也很簡單。它指定單詞或分隔符。
也許值得一試。. .
uj5u.com熱心網友回復:
注意:您曾抱怨過您的代碼速度很慢,但重要的是要了解大多數答案都有可能加快程式速度的選項。即使選項的作者測量了程式的加速,選項在您的機器上也可能更慢,所以不要忘記自己測量執行速度。
如果我是你,我會創建一個單獨的函式來接收一個字串陣列并輸出一個分隔字串陣列。這種方法的問題可能在于,如果分隔符包含另一個分隔符,結果可能不是您所期望的,但它會更容易遍歷字串拆分的不同選項,找到最好的。我的解決方案看起來像這樣(盡管它需要 c 20)
#include <iomanip>
#include <iostream>
#include <ranges>
#include <string_view>
#include <vector>
std::vector<std::string> split_elems_of_array(const std::vector<std::string>& array, const std::string& delim)
{
std::vector<std::string> result;
for(const auto str: array)
{
for (const auto word : std::views::split(str, delim))
{
std::string chunk(word.begin(), word.end());
if(!chunk.empty() && chunk != " ")
result.push_back(chunk delim);
}
}
return result;
}
std::vector<std::string> split_string(std::string str, std::vector<std::string> delims)
{
std::vector<std::string> result = {std::string(str)};
for(const auto&delim: delims)
result = split_elems_of_array(result, delim);
return {result.begin(), result.end()};
}
對于我的機器,我的方法快了 56 倍:67 毫秒對 5112 毫秒。字串長度為 1000000,有 100 個長度為 100 的 delims
uj5u.com熱心網友回復:
這是標準分裂的演算法。如果pop-pap-bab bob按{'-' , ' '}它拆分,它["pop", "pap", "bab", "bob"]不會存盤定界符并且不會檢查空文本。你也可以改變它來做那些事情。
- 定義一個名為 的字串向量
result。 - 定義一個名為 的字串變數
buffer。 - 遍歷你的字串,如果當前字符不是定界符,將它附加到
buffer. - 如果當前字符是定界符,則附加
buffer到結果。 - 結束時回傳
result。
std::vector<std::string> split(std::string str, std::vector<char> delimiters)
{
std::vector<std::string> result;
std::string buffer;
for (const auto ch : str)
{
if (std::find(delimiters.begin(), delimiters.end(), ch) == delimiters.end())
buffer = ch;
else
{
result.insert(result.end(), buffer);
buffer.clear();
}
}
if (buffer.length())
result.insert(result.end(), buffer);
return result;
}
它的時間復雜度是O(nm)。n是 string 的長度,m是 的長度delimiters。
uj5u.com熱心網友回復:
使用 boost expressive 可能是個好主意。它是用于各種字串操作的強大工具,而不是苦苦掙扎于 string::find_xx 和 self for-loop 或 regex。
簡明解釋: as_xpr(" ") 像regex一樣重復匹配1個以上,然后前綴"-"表示最短匹配。如果您將正則運算式決議器定義為sregex rex = "(" >> ( _w | "_") >> ":" >> _d >> ")",它將匹配(port_num:8080). 在這種情況下,“>>”表示決議器的連接,( _w | "_")表示它重復匹配字符或“_”。
#include <vector>
#include <string>
#include <iostream>
#include <boost/xpressive/xpressive.hpp>
using namespace std;
using namespace boost::xpressive;
namespace x = boost::xpressive;
int main() {
string source = "Nigeria is a multi&&national state in--habited by more than 2;;50 ethnic groups speak###ing 500 distinct languages";
vector<string> delimiters{ " ", " ", "&&", "-", ";;", "###"};
vector<sregex> pss{ - as_xpr(delimiters.front()) };
for (const auto& d : delimiters) pss.push_back(pss.back() | - as_xpr(d));
vector<string> ret;
size_t pos = 0;
auto push = [&](auto s, auto e) { ret.push_back(source.substr(s, e)); };
for_each(sregex_iterator(source.begin(), source.end(), pss.back()), {}, [&](smatch const& m) {
if (m.position() - pos) push(pos, m.position() - pos);
pos = m.position() m.str().size();
}
);
push(pos, source.size() - pos);
for (auto& s : ret) printf("%s\n", s.c_str());
}
輸出由多個字串分隔符拆分。
Nigeria
is
a
multi
national
state
in
habited
by
more
than
2
50
ethnic
groups
speak
ing
500
distinct
languages
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/534095.html
標籤:C
