簡體   English   中英

C ++會重新分配std :: string :: erase和…嗎?

[英]C++ does std::string::erase reallocate and…?

第一個問題, std::string::erase重新分配?

第二個問題,是否有更快的方法可以快速刪除std::string某些單詞或短語? 字符串的長度通常約為300K。

如果string::erase要觸發重新分配,則未定義。 您可以通過將string::capacity與調用該方法前后的比較來檢查發生了什么。 刪除字符串的一部分總是會觸發被擦除部分之后的所有字符的副本,因為需要連續存儲字符串。

對於大型字符串的操作,您可能需要考慮使用繩索或std :: list代替。 根據您的操作,結果可能會更快。

21.4.1 / 3

任何delete()或pop_back()成員函數均不得拋出任何異常。

由於在分配器上不存在這種限制,因此我認為可以肯定地說, std::string::erase不而且不能重新分配。

您可能想看看rope 它是為大型字符串設計的重型字符串(得到它嗎?),子字符串操作快得多。 不幸的是,它不是std一部分,而是常見的添加項(在SGI,STLPort和GNU的libstdc ++中)。

請參閱STL繩索-何時何地使用

已經提到過std :: string :: erase是否觸發重新分配取決於實現。 所以我想專注於字符串搜索。 解決此問題的傳統方法是使用Aho-Corasick算法

另外,David Musser撰寫了一篇有關使用Boyer-Moore和Knuth-Morris-Pratt算法混合算法在大型干草堆(字符串)中搜索針(子字符串)的論文。 本文可在此處獲得 適應這一點可能比推出Aho-Corasick實現要簡單得多。

穆瑟(Musser)的方法所展示的行為必須比幼稚的搜索和替換要快。 通過修改BM跳過循環和KNP查找表以考慮要更換的所有針,應該有可能使算法適應您的目的。 預先分配一個輸出緩沖區,並通過將所有未匹配的干草堆段附加到輸出字符串上來迭代構造輸出字符串。 隨着針數的增加和BM / KNP查找的飽和,這種方法的效果會降低。

從我對STL的了解中,我可以看到在std::string::erase期間重新分配字符串的條件是: if (__new_size > this->capacity() || _M_rep()->_M_is_shared())我認為這意味着字符串在erase呼叫期間未重新分配。

  1. 不, std::string::erase不會重新分配-因為它不需要,並且因為C ++的哲學是您不需要為不需要的東西付錢(重新分配時間)。
  2. 取決於您要擦除的內容以及快速含義(快速鍵入或執行)。

首先要做的當然是找到一種快速算法,以查找要刪除的單詞/短語。 然后,如果僅要擦除一個塊,則std::string::erase應該非常適合您的需求。 但是,例如,如果您具有字符串“ 000aa11111bbbbbbb2222222c3333333333”,並且想要刪除所有包含字母的短語,那么一個接一個地查找和擦除它們將導致字符串其余部分的多個副本-'1將被復制一次,' 2將被復制兩次,依此類推。 因此,如果字符串中有許多要刪除的短語,則有可能提高性能-只需單獨復制應保留在字符串中的塊並覆蓋要擦除的塊即可:(|表示迭代器,直到字符串是正確的”):

  • “ 000 | aa11111bbbbb2222222c3333333333”
  • “ 00011111 | 11bbbbb2222222c3333333333”
  • “ 000111112222222 | 2222222c3333333333”
  • “ 0001111122222223333333333 | 33333333”
  • “ 0001111122222223333333333”

這樣,您必須將第一個被刪除的短語之后的每個字符都復制一次。

我正在使用來自MS的VC6,這最后一個DO在std :: string :: erase()調用上重新分配了緩沖區。 我不得不從代碼中刪除所有的delete()調用,因為有時我使用的是大字符串,因此我發現速度變慢了。 因此,請注意您的編譯器,並避免使用指標。 就個人而言,我使用reaffectations str =“”; 作為解決方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM