与其尝试使用基本的字符串数组,不如使用某种方法来跟踪每个单词的出现次数。您可以使用简单的struct 或std::map。在任何一种情况下,您都可以关联一个单词和它被视为单个对象的次数。如果您随后在std::vector 中收集包含单词和计数的所有结构,而不是基本数组,则可以提供一个简单的比较函数来使用std::sort 按单词对向量进行排序,同时保留计数与每个字。
采取使用stuct 的方法,您可以创建一个包含std::string 和计数器的结构,例如:
struct wordcount { /* struct holding word and count */
std::string word;
size_t count;
};
对于wordcount的向量按word排序的比较函数,可以用一个简单的:
/* 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; 为了使函数有用,如果单词已经存在,您可以让它返回向量中的索引(大致相当于数组中的索引),如果不存在则返回 -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,或者将新的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 和然后使用原始副本和计数数组将计数映射回排序输出)。无论您采用哪种方法,关键是您必须有一种方法来保留单词之间的预排序关联以及每个单词与单词的排序后结果的出现次数,然后将计数映射回来到正确的词。使用将单词和计数作为一个单元关联的对象可以解决关联问题。
仔细观察,将它们作为处理它的一种方式。如果您还有其他问题,请告诉我。