2017-05-09 35 views
2

這是用C++編寫的。比方說,我有一個看起來像這樣的字符串"[05]some words here [13]some more words here [17]and so on"什麼是從字符串中提取數據到Map中的有效方法?

我想將這個字符串拆分成一個Map<int, std::string>,其中數字作爲關鍵字,文本作爲下一個代碼作爲值。括號將被完全忽略。

到目前爲止,我一直在使用標準庫和SDL(我正在製作一個小型遊戲),但是我願意安裝boost或任何其他幫助的庫。

我首先想到的是,無論是使用一些增強的正則表達式的功能做了一種正則表達式的查找和替換,或者簡單地將其轉換爲字符數組經歷的每一個字符尋找托架和記錄裏面的電話號碼,但是看起來效率不高,特別是因爲我確信在C++中可能使用這種方法。

+0

*字符數組通過每一個人物去...這將是低效*。爲什麼效率低下?! – CroCo

回答

1

可以利用substr()find_first_of()從字符串中提取的實際數據如下:

#include <string> 
#include <iostream> 
#include <map> 

using std::string; 
using std::cout; 
using std::endl; 
using std::map; 


map<int,string> StrToMap(const string& str) 
{ 
    map<int, string> temMap; 

    for (int i(0); i < str.size(); ++i){ 
     if (str[i] == '['){ 
      string tempIdx = str.substr(i+1, str.find_first_of("]",i)-i-1); 
      int a = i+str.find_first_of("]",i)-i+1; 
      int b = str.find_first_of("[",a)-1; 
      if (b < 0) 
       b = str.size(); 
      string tempStr = str.substr(a, b-a); 
      int idx = std::stoi( tempIdx); 
      temMap[idx] = tempStr; 
     } 
    } 

    return temMap; 
} 


int main(int argc, char* argv[]) 
{ 
    map<int, string> temMap = StrToMap("[05]some words here [13]some more words here [17]and so on"); 

    for (std::map<int, string>::const_iterator it=temMap.begin(); it!=temMap.end(); ++it) 
    std::cout << it->first << " " << it->second << '\n'; 

    return 0; 
} 

結果是

5 some words here 
13 some more words here 
17 and so on 
+0

謝謝你向我展示我的方式錯誤。根據我的測試,你的方法是最快的,這與我期待的相反! – user3445644

0

您可以通過'[''字符拆分字符串並將部分收集到向量中。然後,對於矢量的每個元素,將它分成兩部分('之前'和之後)。首先轉換爲數字並將所有內容放在地圖中。這都將是標準的std方法。

4

您可以使用regex_token_iterator。這裏的基本思想是:

#include <iostream> 
#include <map> 
#include <string> 
#include <vector> 
#include <regex> 

using namespace std; 

map<int, string> extract(const std::string & s) 
{ 
    map<int, string> m; 
    static const regex r("\\s*\\[(\\d+)\\]"); 
    sregex_token_iterator tok(s.begin(), s.end(), r, { -1, 1 }); 
    tok++; // Skip past the first end-of-sequence iterator. 

    for(sregex_token_iterator end; tok != end;) 
    { 
     int num = stoi(*tok, nullptr, 10); 
     if(++tok != end) 
     { 
      m.emplace(make_pair(num, *tok++)); 
     } 
    } 
    return m; 
} 

int main() 
{ 
    auto m = extract("[05]some words here [13]some more words here [17]and so on"); 
    for(auto & p : m) cout << p.first << ": '" << p.second << "'" << endl; 
    return 0; 
} 

這裏,這是搜索和提取模式\s*\[(\d+)\]\s*,這意味着它將之前的方括號後降大任的空白,並創建一個匹配組至少匹配一個數字。

通過對迭代器使用{-1, 1},我們要求的迭代序列提供之前的比賽中的所有文本,然後通過匹配組1

輸出:

5: 'some words here' 
13: 'some more words here' 
17: 'and so on' 

工作的例子是here

+0

謝謝,我能夠學習如何使用regex_token_iterator感謝你的例子! – user3445644

相關問題