将字值转换为具有设定值的键映射
Word value into a key map which has set value
我知道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
}
我认为你没有完全理解这个算法的要求。(顺便问一下,这是家庭作业吗?)
这里的目标是生成一个一致性——每个单词出现的所有列表。set
的作用是保存所有的出现。例如:"苹果"这个词可能出现在第1页、73页和100页。因此,"apple"的映射条目必须包含所有这些值。)
规范化的目的是为了节省读者的检索时间:"apple"、"apple"answers"apples"应该可能都在地图的一个条目中。
理解了这一点,我们可以更新你的程序。
首先,在读取数据之前不要检查eof
。只有在读取数据后进行检查才有意义。实际上,对于这种检查有一个更简单的习惯用法:
string word;
while (fin >> word) {
...
在我看来,我们需要在vector中存储原始单词,然后使用规范化的单词作为映射索引
text.push_back(word);
normalize(word);
现在,更新地图很容易。您不需要pair
,只需使用[]
运算符即可。要认识到,仅仅引用一个地图条目就会导致它突然出现!
concordance[word].insert(text.size()-1);
EDIT将最后一位分开:
concordance[word]
在map中查找由word
索引的条目。如果条目存在,则返回它。如果条目没有退出,则创建它,并返回新形成的条目。.insert
是对由word
索引的map表项所在的set进行的插入操作。text.size()-1
是插入到由word
索引的map表项所在的set中的值。
将它们重新组合在一起,concordance[word].insert(text.size()-1)
查看映射,检索(或创建)指定的set
,然后将数字text.size()-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指出的,这个循环需要一些修正
首先,您的while
循环是错误的,因为eof
标志(或任何其他失败标志)在之后设置,试图从流中读取失败;这意味着,如果尝试读取失败,则尝试将先前读取的word
插入vector两次,而循环中的其余代码在实际上不应该执行时仍然执行。
一个更习惯的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
,并退出循环。
我没有很清楚地理解你的帖子的其余部分,这个问题以及你到底想做什么,所以我不能评论。
- 如何在 perl 中将多维映射从 c++ 转换为哈希
- 将C++映射转换为 Java 映射
- 类型映射资源并将列表转换为矢量(并返回)
- 将多映射转换为空指针,然后转换回多映射
- 如何在没有映射的情况下在枚举和字符串之间进行转换?
- 标准::映射转换器模板
- 将引用对具有shared_ptr作为值的映射转换为对具有shared_ptr const 作为值的映射的引用
- 在映射最小值和最大值时从未签名转换为已签名的最佳方法?
- 在将平截头体从摄影机空间转换为灯光空间以进行阴影映射方面存在主要问题
- 将 JNI -> jobject(基本上是 java 文件中的映射和/或映射的映射)转换为 std::map(c++)
- 将C++映射转换为python字典
- 如何使用STL将结构的矢量转换为映射
- 转换/映射迭代器<A>到迭代器<B>
- 将 STL 映射转换为结构
- 将映射转换为STL中的set
- 将multi_key映射转换为连接多个键的"normal"映射
- 按字符顺序将字符串从映射转换为二维矢量
- 将c++映射转换为jobjectJNI
- 使用 JSONCPP 将字符串映射转换为 JSON
- 将指针的映射转换为对象的映射