我知道map
是什么以及它的一般基本功能,但我不知道为什么set
在这里被使用而不仅仅是声明int i = value
或者什么类似。
我真正想要做的是:在将单词放入向量之后,我想使用相同的单词作为值的键。但我真的不知道使用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
}
答案 0 :(得分:2)
我认为您完全不了解此算法的要求。 (顺便说一句,这是作业吗?)
这里的目标是产生一致性 - 每个单词的所有出现的列表。 set
的要点是保存所有次事件。 (例如:“apple”一词可能出现在第1,73和100页上。因此“apple”的地图条目必须包含所有这些值。)
归一化的目的是为读者保存一致时间:“apple”,“Apple”和“apples”都应该在地图中的一个条目中。
了解这一点,我们可以更新您的计划。
首先,在读取数据之前,切勿检查eof
。只有在读取数据后检查它才有意义。事实上,这个检查有一个更简单的习语:
string word;
while (fin >> word) {
...
在我看来,我们需要将原始字存储在矢量中,然后使用规范化字作为地图索引
text.push_back(word);
normalize(word);
现在,更新地图很容易。您不需要pair
,只需使用[]
运算符即可。意识到仅仅引用一个地图条目就会使它成为现实!
concordance[word].insert(text.size()-1);
编辑打破最后一点:
concordance[word]
在地图中查找由word
编制索引的条目。如果条目存在,则返回该条目。如果条目未退出,则创建该条目,并返回新形成的条目。 .insert
是由word
索引的映射条目所定位的集合上的插入操作。 text.size()-1
是插入到由word
索引的地图条目中的集合中的值。
将它重新组合在一起,concordance[word].insert(text.size()-1)
查看地图,检索(或创建)指定的set
,然后将数字text.size()-1
插入该集合中。
你去吧!
答案 1 :(得分:1)
我不确定你是否在复制代码时犯了错误,或者代码是否故意这样,但是seat
集合没有被使用(除了插入元素,但是因为它是不读/存将丢失),添加到concordance
的所有元素都将成对("",[empty set])
看起来它似乎没有尝试构建索引,即从单词到单词出现的向量中的位置的映射。如果是这种情况,那么如果完成它可能会更好:
std::map<std::string, std::set<int> > concordance;
//...
concordance[word].insert(text.size()-1); // if it does not exists, it will create it
// if it exists it will retrieve it and
// add the new position
此模式通常用于将单词索引到页面中(例如用于书籍),其中集合具有优于矢量的优势,如果单个单词在单个页面中出现100次,则它将保证唯一性将确保不重复页码(您必须在向量中测试)。这不是代码的情况,因为索引是单词向量中的位置,这些单词本身是唯一的。
另请注意,正如Nawaz指出的那样,循环需要进行一些修正。
答案 2 :(得分:0)
首先,你的while
循环是错误的,因为在尝试从流中读取失败后,设置了eof
标志(或任何其他失败标志) ;这意味着,如果尝试读取失败,则尝试将先前读取的word
插入到向量中两次,并且循环中的其余代码仍然执行,而实际上它不应该执行。
一个更惯用的while循环是这样的:
string word;
while( 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);
}
如果尝试阅读(即fin >> word
)失败,则返回std::istream&
隐式转换为false
,循环退出。
我并没有清楚地了解你的其他帖子,问题以及你究竟要做什么,所以我不能对此发表评论。