簡體   English   中英

如何有效地從 std::string 中刪除雙引號(如果存在)

[英]How to efficiently remove double quotes from std::string if they exist

這個問題有重復的風險,例如從 C++ 中的字符串中刪除雙引號,但我看到的所有答案都沒有解決我的問題
我有一個字符串列表,其中一些是雙引號,有些不是,引號總是在開頭和結尾

std::vector<std::string> words = boost::assign::list_of("words")( "\"some\"")( "of which")( "\"might\"")("be quoted");

我正在尋找刪除引號的最有效方法。 這是我的嘗試

for(std::vector<std::string>::iterator pos = words.begin(); pos != words.end(); ++pos)
{
  boost::algorithm::replace_first(*pos, "\"", "");
  boost::algorithm::replace_last(*pos, "\"", "");
  cout << *pos << endl;
}

我能做得比這更好嗎? 我可能有數十萬個字符串要處理。它們可能來自文件或數據庫。 示例中的 std::vector 僅用於說明目的。

如果您知道引號將始終出現在第一個和最后一個位置,您可以簡單地做

if ( s.front() == '"' ) {
    s.erase( 0, 1 ); // erase the first character
    s.erase( s.size() - 1 ); // erase the last character
}

復雜性在字符串的大小上仍然是線性的。 您不能在 O(1) 時間內從std::string的開頭插入或刪除。 如果用空格替換字符是可以接受的,那么就這樣做。

進行檢查可能會很快:

for (auto i = words.begin(); i != words.end(); ++i)
    if (*(i->begin()) == '"')
        if (*(i->rbegin()) == '"')
            *i = i->substr(1, i->length() - 2);
        else
            *i = i->substr(1, i->length() - 1);
    else if (*(i->rbegin()) == '"')
        *i = i->substr(0, i->length() - 1);

它可能不是有史以來最漂亮的東西,但它是 O(n) 的一個小常數。

  if (str.size() > 1) {
    if (str.front() == '"' && str.back() == '"') {
      if (str.size() == 2) {
        str.erase();
      } else {
        str.erase(str.begin());
        str.erase(str.end() - 1);
      }
    }
  }

筆記:

  • erase()函數修改字符串而不是重新分配它。
  • 在空字符串上調用front()會觸發未定義的行為。
  • 此代碼有可能編譯器推斷出兩個erase調用的意圖並進一步優化代碼(一起刪除第一個和最后一個字符是一個標准問題)。

這就是我處理這種情況的方式:

  • 從簡單開始:從完成這項工作的最簡單方法開始,例如 Potatoswatter 的回答。
  • 不要存儲帶引號的字符串:如果可以,請不要存儲帶引號的字符串。 首先在您創建std::vector<std::string>的地方檢查並取消引用字符串。 如果您只是收到一個std::vector<std::string>沒有太多可以做的,因為刪除第一個引號將需要復制字符串的其余部分。
  • 配置文件/基准測試:您可能會驚訝於 100000 條字符串的迭代速度有多快,而最終微優化的數量卻很少。 在某些情況下,您確實需要一點點速度,但請確保了解如何獲得最大收益(分析會告訴您)。
  • 最壞情況:如果在取消引用時絕對必須防止復制整個字符串,則將索引/迭代器存儲到第一個“真實”字符。 這實際上對於“短”字符串可能會更慢,但可能適用於“長”字符串(即,大小為兆字節)。 您還可以創建或查找一個字符串類來處理移動字符串開始而不復制,但這是我的最后選擇。

暫無
暫無

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

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