2009年6月30日 星期二

C++ 沒有 split

C++ 沒有 split()。很多 script language 都有 split 這個好用的東西,但是 C++ 沒有,使用 boost::xpressive 我們可以用七行程式碼實作一個。
std::vector<std::string> split ( const std::string &s ) {
using namespace boost::xpressive ;
sregex_token_iterator begin( s.begin(), s.end(), +_s, -1 ), end;
std::vector<std::string> v ;
std::copy( begin, end, std::back_inserter(v) );
return std::move(v) ;
}

split ( "A B C" ) ; // ["A", "B", "C"]
split ( "A BB\tCCC\n\nDDDD" ) ; // ["A", "BB", "CCC", "DDDD"]
Python 的 split 一樣,切割字元是三種空字元 ' ', '\t', 還有 '\n',而且連續的空白會被忽略。

順帶提一下,這個函數不採用由外部傳入 std::vector<std::string>> 接收 tokens 的設計,而是用 std::move() 把結果傳出來,使用上更直覺簡單,感謝 C++0x 帶給 C++ 更強大的表述能力。

3 則留言:

  1. 只要 一個 return statement 就夠了. 不但把 construction 與 assignment 簡化為一動, 還可享受比 move 更快的 RVO (省掉一個 cheap copy + no-op destruct).

    回覆刪除
  2. 哇,大師降臨耶~我都忘記 vector 還有這個建構子可以用了哈哈~降子的話換成這個版本好了,編譯更快,而且還不用裝 boost。

    vector<string> split(const std::string &s) {
    return vector<string>(
    istream_iterator<string>(istringstream(s)),
    istream_iterator<string>()) ;
    }

    回覆刪除
  3. 就我所知,只要所有return都是同一instance就會用到RVO。

    回覆刪除