2013-11-21 29 views
1

好吧,伙计们...从句子中获取单词并将它们存储在一个字符串矢量中

这是我的集合,它包含所有字母。我将一个单词定义为由该集合中的连续字母组成。

const char LETTERS_ARR[] = {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"}; 
const std::set<char> LETTERS_SET(LETTERS_ARR, LETTERS_ARR + sizeof(LETTERS_ARR)/sizeof(char)); 

我希望这个函数将采取在代表一个句子一个字符串,并返回在句子中的各个单词串的向量。

std::vector<std::string> get_sntnc_wrds(std::string S) { 
    std::vector<std::string> retvec; 
    std::string::iterator it = S.begin(); 
    while (it != S.end()) { 
     if (LETTERS_SET.count(*it) == 1) { 
      std::string str(1,*it); 
      int k(0); 
      while (((it+k+1) != S.end()) && (LETTERS_SET.count(*(it+k+1) == 1))) { 
       str.push_back(*(it + (++k))); 
      } 
      retvec.push_back(str); 
      it += k; 
     } 
     else { 
      ++it; 
     } 
    } 
    return retvec; 
} 

例如,下面的调用应返回字符串“呦”,“耶”等

std::string mystring("Yo, dawg, I heard you life functions, so we put a function inside your function so you can derive while you derive."); 
std::vector<std::string> mystringvec = get_sntnc_wrds(mystring); 

的载体,但一切都正如预期不会。我试着运行我的代码,它将整个句子放入矢量的第一个也是唯一的元素中。我的功能是非常混乱的代码,也许你可以帮助我想出一个更简单的版本。我不希望你能够在我写这个函数的可怜尝试中追踪我的思考过程。

回答

1

它只是一个包围的问题,我的建议是(几乎)从来没有把更多的括号比是必要的,它只是混淆了事情

 while (it+k+1 != S.end() && LETTERS_SET.count(*(it+k+1)) == 1) { 

您的代码字符与1不是count的返回值进行比较。

也不过数量不会返回在这种情况下一个整数我会进一步简化和治疗回报为一个布尔

 while (it+k+1 != S.end() && LETTERS_SET.count(*(it+k+1))) { 
1

试试这个:

#include <vector> 
#include <cctype> 
#include <string> 
#include <algorithm> 

// true if the argument is whitespace, false otherwise 
bool space(char c) 
{ 
    return isspace(c); 
} 

// false if the argument is whitespace, true otherwise 
bool not_space(char c) 
{ 
    return !isspace(c); 
} 

vector<string> split(const string& str) 
{ 
    typedef string::const_iterator iter; 
    vector<string> ret; 
    iter i = str.begin(); 

    while (i != str.end()) 
    { 
    // ignore leading blanks 
    i = find_if(i, str.end(), not_space); 
    // find end of next word 
    iter j = find_if(i, str.end(), space); 
    // copy the characters in [i, j) 
    if (i != str.end()) 
     ret.push_back(string(i, j)); 
    i = j; 
    } 
    return ret; 
} 

split函数会返回一个vectorstring s,每个元素包含一个单词。

此代码取自Accelerated C++书,所以它不是我的,但它的工作原理。还有其他一些使用容器和算法解决本书每日问题的例子。我甚至可以在输出控制台上显示一个文件的内容。强烈推荐。

+0

可能存在除空格之外的字符用于分割(如逗号)。 –

+0

在find_if算法中修改谓词(空格和not_space)并不难。 – mihai

1

你应该std::copy使用string steam像这样:

#include <iostream> 
#include <string> 
#include <sstream> 
#include <algorithm> 
#include <iterator> 
#include <vector> 

int main() { 
    std::string sentence = "And I feel fine..."; 
    std::istringstream iss(sentence); 
    std::vector<std::string> split; 
    std::copy(std::istream_iterator<std::string>(iss), 
       std::istream_iterator<std::string>(), 
       std::back_inserter(split)); 

    // This is to print the vector 
    for(auto iter = split.begin(); 
     iter != split.end(); 
     ++iter) 
    { 
     std::cout << *iter << "\n"; 
    } 
} 
+0

即使我想到了类似的方法,但可能会使用空格以外的字符来分割(如逗号)。 –

+0

@AbhishekBansal这是一个简单的解决方法,因为在解析它之前,可以用字符串中的“,”替换所有的“,”。 – Caesar

+0

那么可以有其他非alpha字符,如'。' '(''*'等。如果你需要替换这些字符,那么IMO会使用stringstream的优势丢失。 –

0

在这里,你做2次失误,我有正确的下面的代码。

首先,它应是

而(((它+ K + 1)!= S.end())& &(LETTERS_SET。COUNT(*(它+ K + 1))== 1))

和,应该通过

移动到下一个它+ =(K + 1);

和代码是

std::vector<std::string> get_sntnc_wrds(std::string S) { 
    std::vector<std::string> retvec; 
    std::string::iterator it = S.begin(); 
    while (it != S.end()) { 
     if (LETTERS_SET.count(*it) == 1) { 
      std::string str(1,*it); 
      int k(0); 

      while (((it+k+1) != S.end()) && (LETTERS_SET.count(*(it+k+1)) == 1)) { 
       str.push_back(*(it + (++k))); 
      } 
      retvec.push_back(str); 
      it += (k+1); 
     } 
     else { 
      ++it; 
     } 
    } 
    return retvec; 
} 

输出已经过测试。

1

我会使用另一个更简单的方法基于std :: string类的成员函数。例如,

const char LETTERS[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 

    std::string s("This12 34is 56a78 test."); 

    std::vector<std::string> v; 

    for (std::string::size_type first = s.find_first_of(LETTERS, 0); 
      first != std::string::npos; 
      first = s.find_first_of(LETTERS, first)) 
    { 
     std::string::size_type last = s.find_first_not_of(LETTERS, first); 
     v.push_back(
      std::string(s, first, last == std::string::npos ? std::string::npos : last - first)); 
     first = last; 
    } 

    for (const std::string &s : v) std::cout << s << ' '; 
    std::cout << std::endl; 
相关问题