【问题标题】:extracting last 2 words from a sequence of strings, space-separated从字符串序列中提取最后两个单词,用空格分隔
【发布时间】:2010-10-06 18:14:25
【问题描述】:

我有任何序列(或句子),我想提取最后 2 个字符串。

例如,

  • sdfsdfds sdfs dfsd fgsd 3 dsfds 应该产生:3 dsfds
  • sdfsd (dfgdg)gfdg fg 6 gg 应该产生:6 gg

【问题讨论】:

  • 另请参阅此问题:stackoverflow.com/questions/53849/…。此外,这与 STL(这是处理容器、迭代器和算法的 std lib 的一部分)关系不大,所以我更改了标签。
  • @sbi: std::string 及其查找方法(rfind 在这种情况下很有用)是 STL 的一部分。所以我宁愿不删除 STL 标签。
  • @Vlad:“STL”是来自原始 STL 的 std lib 的那些部分的俗称。 It is not a synonym for the Standard Library. 有人可能会争论std::string(甚至在问题中都没有提到)在STL来的时候很长一段时间都在标准草案中,后来才“STLified”,是否属于STL。无数的成员函数绝对不是。 (毕竟,算法与容器分离的事实使 STL 与众不同。)我不会为那个标签而争论,但这是错误的。

标签: c++ algorithm string stl tokenize


【解决方案1】:

您可以使用std::string::find_last_of 函数查找空格。

int main()
{
    std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";

    size_t found1 = test.find_last_of( " " );
    if ( found1 != string::npos ) {
        size_t found2 = test.find_last_of( " ", found1-1 );
        if ( found2 != string::npos ) 
            std::cout << test.substr(found2+1, found1-found2-1) << std::endl;
        std::cout << test.substr(found1+1) << std::endl;
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    如果您的字符串是空格分隔的,则以下内容将起作用。

    #include <iostream>
    #include <string>
    #include <sstream>
    #include <vector>
    using namespace std;
    
    int main()
    {
        string str = "jfdf fhfeif shfowejef dhfojfe";
        stringstream sstr(str);
        vector<string> vstr;
    
        while(sstr >> str)
        {
            vstr.push_back(str);
        }
    
        if (vstr.size() >= 2)
            cout << vstr[vstr.size()-2] << ' ';
        if (vstr.size())
            cout << vstr[vstr.size()-1] << endl;
    
        return 0;
    }
    

    【讨论】:

    • 在访问它之前,您可能需要检查向量的大小是否大于 2。
    • 好的,谢谢。我假设会有足够的字符串进行提取。
    • @Donato:(您需要正确@address 评论回复才能显示在其他人的回复标签中。我只是偶然来到这里。)现在投票。
    • @sbi,不知道这个功能。谢谢。我以为是自动的。
    【解决方案3】:

    以错误的顺序返回字符串,但如果这无关紧要,

    std::string s ("some words here"); 
    
    std::string::size_type j;
    for(int i=0; i<2; ++i) {
        if((j = s.find_last_of(' ')) == std::string::npos) {
            // there aren't two strings, throw, return, or do something else
            return 0;
        }   
        std::cout << s.c_str()+j+1;
        s = " " + s.substr(0,j); 
    }  
    

    或者,

    struct extract_two_words {
        friend std::istream& operator>> (std::istream& in , extract_two_words& etw);
        std::string word1;
        std::string word2;
    };
    
    std::istream& operator>> (std::istream& in , extract_two_words& etw) {
        std::string str1, str2;
        while(in) {
            in >> str1;
            in >> str2;
        }
        etw.word2 = str1;
        etw.word1 = str2;
    }
    

    【讨论】:

      【解决方案4】:

      我建议您查看 Boost 库。它具有极大地帮助您的算法和数据结构。以下是使用Boost.StringAlgo 解决问题的方法:

      #include <boost/algorithm/string/split.hpp>
      #include <iostream>
      #include <vector>
      #include <string>
      
      int main()
      {
         std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";
      
         std::vector<std::string> v;
         boost::algorithm::split(v, test, [](char c) { return c==' ';});
         std::cout << "Second to last: " << v.at(v.size()-2) << std::endl;
         std::cout << "Last:           " << v.at(v.size()-1) << std::endl;
      }
      

      我还鼓励您始终使用 vector::at 方法而不是 []。这将为您提供适当的错误处理。

      【讨论】:

        【解决方案5】:
        int main()
        {
             std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds";
             size_t pos = test.length();
             for (int i=0; i < 2; i++)
                 pos = test.find_last_of(" ", pos-1);
             std::cout << test.substr(pos+1) << std::endl;
         }
        

        更简单:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-10
          • 2023-03-08
          • 1970-01-01
          • 2010-12-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-10
          • 1970-01-01
          相关资源
          最近更新 更多