【问题标题】:Splitting a string with delimiter in C++在 C++ 中使用分隔符拆分字符串
【发布时间】:2013-07-12 15:25:56
【问题描述】:

有几个关于这个问题的例子。然而,大多数答案都不是我想要的。

我正在寻找一种方法来实现高效且简单的功能,而不是使用 boost 或任何其他非 STL 库。如果你问我为什么,在大多数编码比赛和面试中,你是不允许使用它们的。

这是我能接近的最接近的:

vector<string> SplitString(const char *str, char c)
{
    vector<string> result;
    do {
        const char *begin = str;
        while(*str != c && *str) {
            str++;
        }
        result.push_back(string(begin, str));
    } while (0 != *str++);
    return result;
}

int main() {

    string mainString = "This is a sentence. Another sentence. The third sentence. This is the last sentence.";
    vector<string> sentences;
    sentences = SplitString(mainString.c_str(), '.');
    while (!sentences.empty()) {
        cout << sentences.back() << endl;
        sentences.pop_back();
    }
    return 0;
}

现在的问题是,它只能有一个字符分隔符而不是字符串。我曾想过实施几种方法,但它们似乎太复杂了。我认为最简单的方法是,将分隔符转换为字符数组,使用c 作为分隔符字符数组的第一个字符:

while(*str != c && *str) {
    str++;
}
const char *beginDelim = *cArr;
while(1) {
    if (*str == *cArr && *str && *cArr) {
       str++;
       cArr++;
    }
    else if (!*cArr) {
        break;
    }
    else if (*cArr) {
        cArr = beginDelim;
    }
}

代码从result.push_back()部分继续。

所以我想知道是否有任何方法可以实现一个高效且简单的函数来使用字符串分隔符分割字符串?

【问题讨论】:

  • 所以你想要一个字符串作为分隔符?
  • 抱歉,问题有点不清楚,修改了最后一句。
  • 是的,有很多方法。到目前为止,您尝试过什么?
  • 为什么不直接使用 string::find()?您也在谈论效率,但您正在将子字符串复制到字符串向量 - 为什么不包含原始字符串和索引向量的结构?

标签: c++ string split delimiter


【解决方案1】:

一般来说,字符串是一个字符指针。因此,您应该搜索分隔符中的第一个字符,然后检查下一个字符。同样在查看您的代码时,我不确定 while (0 != *str++) 是否在做您认为的事情。我认为你的意思是它被空终止。

【讨论】:

    【解决方案2】:

    应该这样做:

    vector<string> SplitString(const char* str,const char* d) {
      vector<string> result;
      size_t len = strlen(d);
      const char* start = str;
      while ( str = strstr(start,d) ) {
        result.push_back(string(start,len));
        start = str + len;
      }
      result.push_back(start);
      return result;
    }
    

    【讨论】:

    • 警告:建议将括号括起来用作此行的真值 " while ( str = strstr(start,d) ) {"
    【解决方案3】:

    这是怎么回事:

    #include <vector>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    vector<string> SplitString(const string &str, const string &delim)
    {
        vector<string> ret;
        string::const_iterator prev = str.begin();
    
        for (string::const_iterator i = str.begin(); i < str.end() - delim.length()+1; ++i)
        {
            if (equal(delim.begin(), delim.end(), i)) {
                ret.push_back(string(prev,i));
                i += delim.length()-1;
                prev = i+1;
            }
        }
    
        ret.push_back(string(prev,str.end()));
    
        return ret;
    }
    

    【讨论】:

      【解决方案4】:
      #include <iostream>
      #include <string>
      #include <vector>
      
      using namespace std;
      
      vector<string> SplitString(string str, const string &delim) {
          vector<string> result;
          size_t found;
          while((found = str.find(delim)) != string::npos) {
              result.push_back(str.substr(0, found));
              str = str.substr(found + delim.size());
          }
          return result;
      }
      
      int main() {
          string mainString = "This is a sentence. Another sentence. The third sentence. This is the last sentence.";
          vector<string> sentences;
      
          sentences = SplitString(mainString, ".");
      
          for(auto& sentence : sentences) {
              cout << sentence << endl;   
          }
          return 0;
      }
      

      【讨论】:

      • 注意:如果输入字符串没有以指定的分隔符结尾,这段代码不会将最终的子字符串压入向量中。一旦str.find(delim) 返回string::npos,如果str 不是空字符串,则应按原样推送。
      【解决方案5】:
      vector<string>split(string str, const char d){
          string temp;
          vector<string>vct;
          for(int i = 0; str[i] != '\0'; i++){
              if(str[i] != d){
                  temp += str[i];
              }else if(!empty(temp)){
                      vct.push_back(temp), temp.clear();
              }
          }
          vct.push_back(temp);
          return vct;
      }
      

      接受两个参数

      • const char d 作为分隔符。
      • string str 作为要拆分的字符串。

      将拆分后的字符串存储在 vectorreturns 中。 虽然,我不确定这段代码的效率。 :)

      【讨论】:

        猜你喜欢
        • 2012-03-01
        • 1970-01-01
        • 2011-11-04
        • 2015-06-29
        • 2018-06-09
        • 2018-04-20
        相关资源
        最近更新 更多