zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    驱动开发环境安装
    FireMonkey下的异形窗体拖动(句柄转换)
    Microsoft Win32 Programmer's Reference.chm
    Qt 访问网络的 HttpClient(封装QNetworkAccessManager,且有服务端)
    JBPM4 安装和配置
    DDD:谈谈数据模型、领域模型、视图模型和命令模型
    多个文件目录下Makefile的写法
    .NET程序集1
    Ajax初步理解
    Kemaswill 机器学习 数据挖掘 推荐系统 Ranking SVM 简介
  • 原文地址:https://www.cnblogs.com/lexus/p/2874899.html
Copyright © 2011-2022 走看看