从句子中获取单词并将其存储在字符串向量中

时间:2013-11-21 06:13:18

标签: c++

好吧,伙计......

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

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

例如,以下调用应该返回字符串“Yo”,“dawg”等的向量。

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);

但一切都没有按计划进行。我尝试运行我的代码,它将整个句子放入向量的第一个也是唯一的元素。我的功能是非常混乱的代码,也许你可以帮我提出一个更简单的版本。我不希望你能够在我写这个功能的可怜尝试中追踪我的思维过程。

5 个答案:

答案 0 :(得分:1)

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

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

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

虽然count确实在这个上下文中返回一个整数,但我会进一步简化并将return视为布尔值

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

答案 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个,每个元素包含一个单词。

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

答案 2 :(得分:1)

您应该string steamstd::copy一样使用:

#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";
    }
}

答案 3 :(得分: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;

答案 4 :(得分:0)

这里你犯了两个错误,我在下面的代码中有正确的错误。

首先,它应该是

  

while(((it + k + 1)!= S.end())&amp;&amp;(LETTERS_SET.count(*(it + 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;
}

输出已经过测试。