计算单词的出现次数

时间:2020-10-03 07:06:24

标签: c++ loops count ifstream

我正在尝试从输入文件中查找给定单词的出现,并且能够正确计算字母/字符的出现,但是当我尝试查找单词时,程序仅返回计数为0。我在做什么错了?

ifstream input("input.txt");
input.open("input.txt");
string video = "video", ands = "and";
string str1((istreambuf_iterator<char>(input)),
    istreambuf_iterator<char>());
int videocount = 0, sentcount = 0, wordcount = 0, wordcountand = 0, wordcountand2 = 0;
for (int i = 0; i < str1.length(); i++)
{
    if (str1 == video) {
        ++videocount;
    }

    if (str1[i] == '.') {
        sentcount++;
    }
    if (str1[i] == ' ') {
        wordcount++;
    }
    if (str1 == ands) {
        wordcountand++;
    }
}

编辑:我只是更改了文件读取方式,并且一切正常。

while (input >> filewords) {
      {wordcount++; }
      if (filewords == word1) {
          ++videocount;
      }
      if (filewords == word2) {
          wordcountand++;
      }
        for (int i = 0; i < filewords.length(); i++) {
            if (filewords[i] == '.') {
                sentcount++;
            }   
        }
    }

1 个答案:

答案 0 :(得分:0)

基本上,该问题已在评论中得到了回答。您无法将搜索字符串与存储在变量“ str1”中的完整文本文件进行比较。结果当然总是假的。

等于运算符==不会查找子字符串。这已经使我们得到了答案,就是我们要使用的算法。我们将使用std::string.substr。有关功能的说明,请参见here。功能参数为:

  • 开始位置
  • 子字符串的长度

因此,我们需要找到一个单词的开始位置和一个单词的结束位置。这样,我们就可以计算出一个单词的长度,即“结束位置”-“开始位置”。

但是如何识别一个单词?一个单词通常由字母数字字符组成。而且,如果我们遍历全文,并比较之前的选中字符和当前评估的字符,则可以声明以下内容:

  • 如果先前的字符不是字母数字,而当前字符是,则我们找到了单词的开头。然后,我们将记住索引,即该单词的开始位置。
  • 如果先前的字符是字母数字,而当前ist不是,那么我们发现单词的结尾。然后我们可以开始比较,因为我们知道开始结束位置。

然后,类似word = str1.substr(startPosition, endPosition-startPosition);的单词会给我们一个单词。我们可以将其与搜索词进行比较,例如:

if (word == video) ++videocount;

但是我们可以走得更远。使用非常简单的标准方法,我们可以存储和计算所有单词。为此,我们可以使用std::mapstd::unordered_map。我们使用std::map的索引运算符。请参阅here。特别要读一句话:

返回对映射到与key等效的键的值的引用,如果该键尚不存在,则执行插入操作。

因此,它将创建一个新条目,或者找到一个现有条目。在任何情况下,都将返回引用(已存在或新创建的条目)。而且那将增加。然后,结果可能像这样:

wordCounter[text.substr(startIndexOfWord, index - startIndexOfWord)]++

因此,在这里,我们首先使用已经描述的算法构建一个子字符串。然后,可以找到此子字符串或将其添加到std::map中。无论如何,都会返回一个引用,我们将对其进行递增。

最后,我们将仅输出所有单词和计数器。

在以下提议中,我将使用C ++ 17和C ++ 17的功能,例如带有初始化程序或结构化绑定的if语句。因此,您需要为编译器启用C ++ 17。

请参阅:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <cctype>
#include <vector>
#include <map>
#include <iomanip>

int main() {

    // Open the input file and check, if that works
    if (std::ifstream ifs("input.txt"); ifs) {

        // Read the complete text file into a string variable
        std::string text(std::istreambuf_iterator<char>(ifs), {});

        // Define the counters
        size_t sentenceCounter{};
        std::map<std::string, size_t> wordCounter{};
        size_t overallWordCounter{};

        // And temporary storage of characters from the complete text
        char currentCharacter{};    char lastCharacter{};

        // Here we stort the index of a word start
        size_t startIndexOfWord{};

        // Iterate over all characters from the source file
        for (size_t index{}; index < text.length(); ++index) {

            // Read the current character
            const char currentCharacter = text[index];

            // Each dot will be counted as an indicator for a sentence
            if ('.' == currentCharacter) ++sentenceCounter;

            // Now check, if we have found the start of a word. The we will just store the index
            if (std::isalnum(currentCharacter) and not std::isalnum(lastCharacter))
                startIndexOfWord = index;

            // Now, check, if we found the end of a word. Add to map and increment counter
            if (std::isalnum(lastCharacter) and not std::isalnum(currentCharacter)) 
                wordCounter[text.substr(startIndexOfWord, index - startIndexOfWord)]++;

            // The next lastCharacter is the currentCharacter of now
            lastCharacter = currentCharacter;
        }

        // Go through the complete map
        for (const auto& [word, count] : wordCounter) {
            // SHow words and counters
            std::cout << std::left << "Word: " << std::setw(30) << word << " Count: " << count << "\n";
            // Calculate overall sum of words
            overallWordCounter += count;
        }
        // Show final result
        std::cout << "\nWords overall: \t" << overallWordCounter << "\nSentences: \t" << sentenceCounter << '\n';
    }
    else {
        std::cerr << "\n***Error: Could not open input file.\n";
    }
    return 0;
}

当然,还有许多其他可能的解决方案,尤其是对于std::regex

如果您有任何问题,我很乐意回答

相关问题