извлечение последних 2 слов из последовательности строк, разделенных пробелом - PullRequest
2 голосов
/ 06 октября 2010

У меня есть любая последовательность (или предложение), и я хочу извлечь последние 2 строки.

Например,

  • sdfsdfds sdfs dfsd fgsd 3 dsfds должно дать: 3 dsfds
  • sdfsd (dfgdg)gfdg fg 6 gg должен произвести: 6 gg

Ответы [ 5 ]

4 голосов
/ 06 октября 2010

Вы можете использовать функцию 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 голосов
/ 06 октября 2010

Следующее будет работать, если ваши строки разделены пробелами.

#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;
}
1 голос
/ 10 октября 2010
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;
 }

Проще:)

1 голос
/ 09 октября 2010

Я бы посоветовал вам взглянуть на библиотеку 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 вместо []. Это даст вам правильную обработку ошибок.

1 голос
/ 06 октября 2010

Возвращает строки в неправильном порядке, но если это не имеет значения,

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;
}
...