【问题标题】:C++ Counting words in a file between two wordsC ++计算文件中两个单词之间的单词
【发布时间】:2012-11-15 17:51:09
【问题描述】:

我目前正在尝试计算文件中的字数。在此之后,我打算让它计算文件中两个单词之间的单词。例如。我的文件可能包含。 “你好,我的名字是詹姆斯”。我想数单词,所以 5。然后我想数“Hello”和“James”之间的单词数,所以答案是 3。我无法完成这两项任务。 主要是因为不确定如何构建我的代码。 在这里的任何帮助将不胜感激。我目前使用的代码是使用空格来计算单词。

这是我的代码:

readwords.cpp

string ReadWords::getNextWord()
{
    bool pWord = false;
    char c;
    while((c = wordfile.get()) !=EOF)
    {
        if (!(isspace(c)))
        {
            nextword.append(1, c);
        }

        return nextword;
    }
}

bool ReadWords::isNextWord()
{
    if(!wordfile.eof())
    {
        return true;
    }
    else
    {
        return false;
    }
}

main.cpp

main()
{
    int count = 0;
    ReadWords rw("hamlet.txt");
    while(rw.isNextWord()){
        rw.getNextWord();
                count++;
    }
    cout << count;
    rw.close();
}

目前它所做的是计算字符数。我敢肯定这只是一个简单的修复和我错过的一些愚蠢的事情。但我已经尝试了足够长的时间来寻求帮助。

非常感谢任何帮助。 :)

【问题讨论】:

  • c++?将标记化的单词附加到向量,找到这两个单词,减去索引。随意处理重复的单词
  • 您也意识到 isNextWord() 几乎毫无意义,对吧?只需添加一个!在你原来的状态或采取替代路径
  • 我个人建议将单词读入 char 数组开始。该文件在内存中后将更易于使用,并且它允许您处理一般情况 - 即 GetWordCountBetween(string word1, string word2) 而无需执行更多文件 IO。

标签: c++ file count words


【解决方案1】:

您可以简单地使用istream::operator&lt;&lt;() 来读取空格分隔的单词,而不是逐个字符地解析文件。 &lt;&lt; 返回流,当仍然可以从中读取流时,其计算结果为 truebool

vector<string> words;
string word;
while (wordfile >> word)
    words.push_back(word);

使用&lt;iterator&gt;&lt;algorithm&gt; 实用程序有一个常见的公式,它更冗长,但可以与其他迭代器算法组合:

istream_iterator<string> input(wordfile), end;
copy(input, end, back_inserter(words));

然后你就有了单词的数量,并且可以随心所欲地使用它们:

words.size()

如果您想查找"Hello""James",请使用&lt;algorithm&gt; 标头中的find() 将迭代器获取到它们的位置:

// Find "Hello" anywhere in 'words'.
const auto hello = find(words.begin(), words.end(), "Hello");

// Find "James" anywhere after 'hello' in 'words'.
const auto james = find(hello, words.end(), "James");

如果它们不在向量中,find() 将返回 words.end();出于说明的目的忽略错误检查,您可以通过计算它们之间的差异来计算它们之间的单词数,并调整范围内包含"Hello"

const auto count = james - (hello + 1);

您可以在这里使用operator-(),因为std::vector::iterator 是一个“随机访问迭代器”。更一般地,您可以使用来自&lt;iterator&gt;std::distance()

const auto count = distance(hello, james) - 1;

这样的好处是更能描述你实际在做什么。另外,为了将来参考,这种代码:

bool f() {
    if (x) {
        return true;
    } else {
        return false;
    }
}

可以简化为:

bool f() {
    return x;
}

因为x 已经被转换为bool 用于if

【讨论】:

  • find(words.begin(), words.end(), "James") 应该是 find(hello, words.end(), "James"),否则可能会在 Hello 之前找到 James。
【解决方案2】:

计数:

std::ifstream infile("hamlet.txt");
std::size_t count = 0;
for (std::string word; infile >> word; ++count) { }

仅在开始和停止之间计数:

std::ifstream infile("hamlet.txt");
std::size_t count = 0;
bool active = false;

for (std::string word; infile >> word; )
{
     if (!active && word == "Hello") { active = true; }
     if (!active) continue;
     if (word == "James") break;
     ++count;
}

【讨论】:

    【解决方案3】:

    我认为“返回下一个单词;”应该改为“else return nextword;”否则,无论字符是什么,您每次都会从函数 getNextWord 返回。

    string ReadWords::getNextWord()
    {
        bool pWord = false;
        char c;
        while((c = wordfile.get()) !=EOF)
        {
            if (!(isspace(c)))
            {
                nextword.append(1, c);
            }
    
            else return nextword;//only returns on a space
        }
    }
    

    【讨论】:

      【解决方案4】:

      统计所有单词:

      std::ifstream f("hamlet.txt");
      std::cout << std::distance (std::istream_iterator<std::string>(f),
                                  std::istream_iterator<std::string>()) << '\n';
      

      在两个单词之间计数:

      std::ifstream f("hamlet.txt");
      std::istream_iterator<std::string> it(f), end;
      int count = 0;
      while (std::find(it, end, "Hello") != end)
        while (++it != end && *it != "James")
          ++count;
      std::cout << count;
      

      【讨论】:

        【解决方案5】:

        试试这个: 线下

        nextword.append(1, c);
        

        添加

        continue;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 1970-01-01
          • 2012-04-13
          • 1970-01-01
          • 2018-12-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多