我知道什么是 map
以及它的一般基本功能,但我不知道为什么这里使用 set
而不是仅仅声明 int i = value
或类似的东西。
我真正想做的是:将单词放入 vector 后,我还想使用相同的单词作为值的键。但我真的不知道使用 map
来做到这一点的全部目的。不确定我是否提供了足够的信息,只是询问您还需要什么,我会回复。
我只提供了一个 readWords
函数,但如果有人需要完整的代码,包括头文件、类和主文件,那么我也可以把它们放上来。
我在帮助下将部分代码写在那里,但老实说,我不知道它在 push_back()
函数之后做了什么。
/* Read word-by-word from filename and store words in text vector.
* Also use normalized version of word as key in concordance map
* The value associated with each key in the map is a set whose
* keys are the associated indices into the vector.
*/
void Concordance::readWords(char * filename){
ifstream fin(filename, ifstream::in);
if (fin.is_open()){
while(!fin.eof()){
string word;
fin >> word;
normalize(word);
text.push_back(word); //puts word into vector
set<int> seat;
seat.insert(text.size()-1);
pair<string, set<int> > pear;
concordance.insert(pear);
}
}
else{
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
fin.close(); //closes the filename
}
最佳答案
我不认为你完全理解这个算法的要求。 (顺便问一下,这是作业吗?)
这里的目标是生成一个索引——每个单词所有出现的列表。 set
的要点是保存所有 的出现。 (例如:“apple”一词可能出现在第 1、73 和 100 页上。因此“apple”的 map 条目必须包含所有这些值。)
规范化的目的是为了节省索引时间的读者:“apple”、“Apple”和“apples”应该都在 map 的一个条目中。
了解这一点,我们可以更新您的程序。
首先,永远不要在读取数据之前检查 eof
。只有在读取数据后检查它才有意义。事实上,这个检查有一个更简单的习惯用法:
string word;
while (fin >> word) {
...
在我看来,我们需要将原始单词存储在 vector 中,然后使用归一化单词作为映射索引
text.push_back(word);
normalize(word);
现在,更新 map 非常容易。您不需要对
,只需使用[]
运算符。意识到仅仅引用一个 map 条目就会导致它突然出现!
concordance[word].insert(text.size()-1);
编辑 打破最后一点:
concordance[word]
在 map 中查找由 word
索引的条目。如果该条目存在,则将其返回。如果条目不存在,则创建它,并返回新形成的条目。 .insert
是对word
索引的map入口所在集合的插入操作。 text.size()-1
是插入到位于由 word
索引的映射条目处的集合中的值。
将其放回原处,concordance[word].insert(text.size()-1)
查看 map ,检索(或创建)指示的集
,然后将数字 text.size()-1
插入该集合。
给你!
关于c++ - 将字值转换为具有设定值的键映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5888364/