将字值转换为具有设定值的关键映射

时间:2011-05-04 18:44:03

标签: c++ stl map set

我知道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
}

3 个答案:

答案 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,循环退出。

我并没有清楚地了解你的其他帖子,问题以及你究竟要做什么,所以我不能对此发表评论。