簡體   English   中英

計算一個詞的出現次數

[英]Counting occurrences of a word

我正在嘗試從輸入文件中查找給定單詞的出現次數,並且我能夠正確計算字母/字符的出現次數,但是當我嘗試查找單詞時,程序只會將計數返回為 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++;
            }   
        }
    }

基本上,這個問題已經在評論中得到了回答。 您不能將搜索字符串與存儲在變量“str1”中的完整文本文件進行比較。 結果當然總是假的。

等號運算符==不查找子字符串。 這已經給我們帶來了答案,即我們想要使用的算法。 我們將使用std::string.substr 有關該功能的說明,請參見此處 函數參數為:

  • 起始位置
  • 子串長度

所以,我們需要找到一個詞的開始位置和一個詞的結束位置。 有了這個,我們可以計算一個單詞的長度,即“結束位置” - “開始位置”。

但是如何識別一個詞呢? 一個詞通常由字母數字字符組成。 如果我們遍歷整個文本,並將前一個檢查的字符與當前評估的字符進行比較,我們可以聲明以下內容:

  • 如果前一個字符不是字母數字,而當前是,那么我們找到了單詞的開頭。 然后我們會記住索引,那個詞的開始位置。
  • 如果前一個字符是字母數字,而當前不是,那么我們找到了單詞的結尾。 然后我們可以開始比較,因為我們知道開始結束位置。

然后,像word = str1.substr(startPosition, endPosition-startPosition); 會給我們一個詞。 我們可以將其與我們的搜索詞進行比較,例如:

if (word == video) ++videocount;

但我們可以走得更遠。 使用非常簡單的標准方法,我們可以存儲和計算所有單詞。 為此,我們可以使用std::mapstd::unordered_map 我們使用std::map的索引運算符。 請看這里 尤其是讀這句話:

返回對映射到與 key 等效的鍵的值的引用,如果這樣的鍵不存在,則執行插入。

因此,它將創建一個新條目,或者查找現有條目。 在任何情況下,都將返回一個引用(對已經存在的或新創建的條目)。 這將增加。 這可能會以類似的方式結束:

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

所以,在這里,我們首先使用已經描述的算法構建一個子字符串。 然后找到此子字符串或將其添加到std::map 在任何情況下,都會返回一個引用,我們將增加該引用。

最后,我們將簡單地輸出所有單詞和計數器。

在下面的提案中,我使用了 C++17 和 C++17 的特性,比如帶有初始值設定項或結構化綁定的if -statment。 所以你需要為你的編譯器啟用 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

如果您有任何問題,我很樂意回答

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM