• split函数的实现


    JeffChen

    split函数的实现

    2013年1月17日 jeffchen 2 条评论

    前几天朋友问我要几道C++面试题,我说你让他先写一个string的split函数吧,类似C语言里的strtok. 现在想想自己的代码里,split函数的实现真是兴之所至,想到用什么方法就用什么方法:

    一种方法是用stringstream,然后用getline:

    void split(const std::string &s, char delim, std::vector<std::string> &elems) {
        std::stringstream ss(s);
        std::string item;
        while(std::getline(ss, item, delim)) {
            elems.push_back(item);
        }
    }

    也可以用regex实现:

    void split(const string &s,const string &delim,vector<string>&elems){
    	regex reg(delim);
    	sregex_token_iterator it(s.begin(),s.end(),reg,-1);
    	sregex_token_iterator end;
    	while (it!=end)
    	{
    		elems.push_back(*it++);
    	}
    }

    然后去stackoverflow上search了一把,这个问题竟然在上面C++ tag问题中名列前茅!
    支持各种定制的template实现:

    template < class ContainerT >
    void tokenize(const std::string& str, ContainerT& tokens,
                  const std::string& delimiters = " ", const bool trimEmpty = false)
    {
       std::string::size_type pos, lastPos = 0;
       while(true)
       {
          pos = str.find_first_of(delimiters, lastPos);
          if(pos == std::string::npos)
          {
             pos = str.length();
     
             if(pos != lastPos || !trimEmpty)
                tokens.push_back(ContainerT::value_type(str.data()+lastPos,
                      (ContainerT::value_type::size_type)pos-lastPos ));
             break;
          }
          else
          {
             if(pos != lastPos || !trimEmpty)
                tokens.push_back(ContainerT::value_type(str.data()+lastPos,
                      (ContainerT::value_type::size_type)pos-lastPos ));
          }
          lastPos = pos + 1;
       }
    };

    使用string提供的find of函数实现:

    void Tokenize(const string& str,
                          vector<string>& tokens,
                          const string& delimiters = " ")
    {
        // Skip delimiters at beginning.
        string::size_type lastPos = str.find_first_not_of(delimiters, 0);
        // Find first "non-delimiter".
        string::size_type pos     = str.find_first_of(delimiters, lastPos);
     
        while (string::npos != pos || string::npos != lastPos)
        {
            // Found a token, add it to the vector.
            tokens.push_back(str.substr(lastPos, pos - lastPos));
            // Skip delimiters.  Note the "not_of"
            lastPos = str.find_first_not_of(delimiters, pos);
            // Find next "non-delimiter"
            pos = str.find_first_of(delimiters, lastPos);
        }
    }

    如果是用空格分离,还有更简洁的方法:

    void split(const string &s,const string &delim,vector<string>&elems){
        string buf;
        stringstream ss(s); 
        while (ss >> buf)
            elems.push_back(buf);
    }

    JeffChen » split函数的实现

    split函数的实现

    前几天朋友问我要几道C++面试题,我说你让他先写一个string的split函数吧,类似C语言里的strtok. 现在想想自己的代码里,split函数的实现真是兴之所至,想到用什么方法就用什么方法:

    一种方法是用stringstream,然后用getline:

    void split(const std::string &s, char delim, std::vector<std::string> &elems) {
        std::stringstream ss(s);
        std::string item;
        while(std::getline(ss, item, delim)) {
            elems.push_back(item);
        }
    }

    也可以用regex实现:

    void split(const string &s,const string &delim,vector<string>&elems){
    	regex reg(delim);
    	sregex_token_iterator it(s.begin(),s.end(),reg,-1);
    	sregex_token_iterator end;
    	while (it!=end)
    	{
    		elems.push_back(*it++);
    	}
    }

    然后去stackoverflow上search了一把,这个问题竟然在上面C++ tag问题中名列前茅!
    支持各种定制的template实现:

    template < class ContainerT >
    void tokenize(const std::string& str, ContainerT& tokens,
                  const std::string& delimiters = " ", const bool trimEmpty = false)
    {
       std::string::size_type pos, lastPos = 0;
       while(true)
       {
          pos = str.find_first_of(delimiters, lastPos);
          if(pos == std::string::npos)
          {
             pos = str.length();
     
             if(pos != lastPos || !trimEmpty)
                tokens.push_back(ContainerT::value_type(str.data()+lastPos,
                      (ContainerT::value_type::size_type)pos-lastPos ));
             break;
          }
          else
          {
             if(pos != lastPos || !trimEmpty)
                tokens.push_back(ContainerT::value_type(str.data()+lastPos,
                      (ContainerT::value_type::size_type)pos-lastPos ));
          }
          lastPos = pos + 1;
       }
    };

    使用string提供的find of函数实现:

    void Tokenize(const string& str,
                          vector<string>& tokens,
                          const string& delimiters = " ")
    {
        // Skip delimiters at beginning.
        string::size_type lastPos = str.find_first_not_of(delimiters, 0);
        // Find first "non-delimiter".
        string::size_type pos     = str.find_first_of(delimiters, lastPos);
     
        while (string::npos != pos || string::npos != lastPos)
        {
            // Found a token, add it to the vector.
            tokens.push_back(str.substr(lastPos, pos - lastPos));
            // Skip delimiters.  Note the "not_of"
            lastPos = str.find_first_not_of(delimiters, pos);
            // Find next "non-delimiter"
            pos = str.find_first_of(delimiters, lastPos);
        }
    }

    如果是用空格分离,还有更简洁的方法:

    void split(const string &s,const string &delim,vector<string>&elems){
        string buf;
        stringstream ss(s); 
        while (ss >> buf)
            elems.push_back(buf);
    }
  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/lexus/p/2874899.html
Copyright © 2020-2023  润新知