c++ - 带排序 C++ 的字数统计

标签 c++ sorting word-count

这是我的数据结构类问题。 我完全不知道如何处理它,任何人都可以给一些提示吗?

  1. 如何停止程序并保证输出能正确输出?
  2. 我是否必须处理映射?

the question paper I had from the professor

以下是我的编码示例:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s [100];

    for (int i = 0; i < 100; i++) {
        cin >> s[i];
        s[i] = Sort(s[i], s[i+1]);
    }


    //check the number of time the words repeatcout the answer
    for (int i = 0; i < 100; i++) {
        cout << s[i] << count (s[i],s[i+1]) <<endl;
    }
    return 0;
}


string Sort(string current, string next ) {
    if (current > next) {
        string temp = current;
        current = next;
        next = temp;
    }
    else {
        return current;
    }
}

int count(string word, string Nextword) {
    int count;
    if (word == Nextword) {
        count++;
    }
    else {
        return count;
    }
}

最佳答案

与其尝试使用基本的字符串数组,您还需要一些方法来跟踪每个单词出现的次数。您可以使用简单的 structstd::map。在任何一种情况下,您都可以将一个词与它被视为单个对象的次数相关联。如果您随后将包含单词和计数的所有结构收集到 std::vector 而不是基本数组中,您可以提供一个简单的比较函数来使用 std::sort 按单词对 vector 进行排序,同时保留计数与每个单词的关联。

采用结构的方法,您可以创建一个包含std::string 和计数器的结构,例如:

 struct wordcount {      /* struct holding word and count */
    std::string word;
    size_t count;
};

对于按 wordwordcount vector 进行排序的比较函数,您可以使用一个简单的方法:

/* compare function to sort vector of struct by words */
bool cmp (const wordcount& a, const wordcount& b)
{
    return a.word < b.word;
}

使用结构,您将需要遍历到目前为止看到的单词,以确定您是否只需要增加现有单词的 count 或添加新的 wordcount 使用 count = 1; 将结构构造到您的 vector 中 为了使该函数有用,您可以让它返回 vector 中的索引(大致相当于数组中的索引)如果单词已经存在,如果不存在则返回 -1

/* interate over each struct in vector words to find word */
int findword (const std::vector<wordcount>& words, 
                const std::string& word)
{
    for (auto w = words.begin(); w != words.end(); w++)
        if (w->word == word)            /* if word found */
            return w - words.begin();   /* return index */

    return -1;  /* return word not found */
}

根据返回值,您可以增加索引处的 count,或向 vector 添加新的 wordcount。使用上面的一个简短的实现是:

int main (int argc, char **argv) {

    if (argc < 2) { /* validate filename given as argument */
        std::cerr << "error: insufficient input.\n"
                << "usage: " << argv[0] << "<filename>\n";
        return 1;
    }

    std::string word;                   /* string to hold word */
    std::vector<wordcount> words {};    /* vector of struct wordcount */
    std::fstream f (argv[1]);           /* file stream */

    while (f >> word) {                 /* read each word from file */
        int idx = findword (words, word);   /* alread exists, get index */
        if (idx != -1) {                /* if index found */
            words[idx].count++;         /* increment count */
        }
        else {  /* otherwise new word */
            wordcount tmp = {word, 1};  /* initialize struct */
            words.push_back(tmp);       /* add to vector */
        }
    }

    std::sort (words.begin(), words.end(), cmp);    /* sort by words */

    for (auto& w : words)   /* output results */
        std::cout << w.word << " " << w.count << '\n';
}

如果将以上所有部分放在一起,您将得到:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

struct wordcount {      /* struct holding word and count */
    std::string word;
    size_t count;
};

/* compare function to sort vector of struct by words */
bool cmp (const wordcount& a, const wordcount& b)
{
    return a.word < b.word;
}

/* interate over each struct in vector words to find word */
int findword (const std::vector<wordcount>& words, 
                const std::string& word)
{
    for (auto w = words.begin(); w != words.end(); w++)
        if (w->word == word)            /* if word found */
            return w - words.begin();   /* return index */

    return -1;  /* return word not found */
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate filename given as argument */
        std::cerr << "error: insufficient input.\n"
                << "usage: " << argv[0] << "<filename>\n";
        return 1;
    }

    std::string word;                   /* string to hold word */
    std::vector<wordcount> words {};    /* vector of struct wordcount */
    std::fstream f (argv[1]);           /* file stream */

    while (f >> word) {                 /* read each word from file */
        int idx = findword (words, word);   /* alread exists, get index */
        if (idx != -1) {                /* if index found */
            words[idx].count++;         /* increment count */
        }
        else {  /* otherwise new word */
            wordcount tmp = {word, 1};  /* initialize struct */
            words.push_back(tmp);       /* add to vector */
        }
    }

    std::sort (words.begin(), words.end(), cmp);    /* sort by words */

    for (auto& w : words)   /* output results */
        std::cout << w.word << " " << w.count << '\n';
}

示例使用/输出

针对您的示例输入运行,您将收到。

$ ./bin/wordcount dat/webpage.txt
Computer 1
algorithm 1
analysis 1
and 1
computer 3
department 1
design 2
quantum 1
science 1
system 1

解决此类问题的方法有很多。它可以用普通的旧数组来完成,但是你会跟踪单词并在一些单独的数组(或数组)中计数,然后编写你自己的排序(或在一个上使用 C qsort保存单词的数组,然后使用原始拷贝和计数数组将计数映射回排序后的输出)。无论您采用何种方法,关键是您必须有一种方法来保留单词之间的预排序关联以及它们各自出现的次数与您单词的排序后结果,然后是一种将计数映射回来的方法到正确的词。使用将单词和计数作为一个单元关联的对象可以解决关联问题。

审视事物,将它们作为解决问题的一种方式。如果您还有其他问题,请告诉我。

关于c++ - 带排序 C++ 的字数统计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58315956/

相关文章:

c++ - std::string 一个容器

hadoop - hadoop字数示例

grep - 计算非常大文件中的单词出现次数(运行时内存耗尽) grep -o foo | wc -l

c++ - 使用 push_back 将 vector<double> 放入 vector<vector<double>>

C++:如何将字符串对象复制到 int 数组?

c++ - 在 v8 中将字符串转换为函数

ios - 如何修复无法将类型 'AnyObject' 的值转换为预期参数类型 '_?' 错误?

Python列表操作: Given a list of ranges number,返回组合范围的列表

arrays - 如何在 Swift 中将正确位置的元素插入到排序数组中?

hadoop - Mapreduce WordCount 示例给出错误的输出