创建按顺序索引的有序映射
Creating a Sequentially Indexed Ordered Map
下面的代码显示了我想创建的一个非常基本但必不可少的功能,并且目前遇到一些令人讨厌的运行时错误,我自己无法调试。我一直在努力为我正在寻找的东西写一个解决方案,这是我最接近的。非常感谢任何帮助确定此实现的修复或重新设计!
这是类。我正在寻找的是一个地图,它仍然可以执行其运算符[key]功能,但也可以在添加元素时按顺序迭代。我试图通过有一个用于查找的映射来做到这一点,其值是指向在相应对的向量中保存的真实值的指针。
template <typename t>
class IndexedMap {
public:
t& operator [] (string s) {
bool nu = true;
for (auto& e : actual) // for each pair
if (e.first == s) // if exist
nu = false;
if (nu == true) { // if needs created
actual.push_back(pair <string, t>()); // create proper pair
actual.back().first = s; // assign key
// create copy in map @ same key pointing to actual value
lookup[s] = &actual.back().second;
}
return *lookup[s]; // return reference to value
}
typename vector <pair <string, t>>::iterator begin () {
return actual.begin();
}
typename vector <pair <string, t>>::iterator end () {
return actual.end();
}
private:
vector <pair <string, t>> actual;
map <string, t*> lookup;
};
这个实现"适用于"以下测试.cpp - 这意味着它将运行,我实际上确实看到了我正在寻找的结果,但是在测试退出时.cpp我遇到了一些涉及调用 free() 的疯狂错误,我不确定这是如何发生的或如何修复。
测试.cpp :
int main () {
IndexedMap <vector <int>> test;
test["BILLS"]; test["GAS"];
test["GROCERY"]; test["PETS"];
test["TAKEOUT"]; test["OTHER"];
int i = 0;
for (auto e : test) // check order
cout << e.first << endl;
for (auto& e : test) // assign 3 unique values to each vector
for (int f = 0; f < 3; ++f, ++i)
e.second.push_back(i);
for (auto e : test) { // display them
cout << e.first << ":" << endl;
for (auto f : e.second)
cout << f << endl;
}
vector <int> blank; // test modifying a value
test["GAS"] = blank;
for (auto e : test["GAS"])
cout << e << endl;
cout << "hopefully empty?" << endl;
}
我希望这不会像我解释或写出来的方式那样令人困惑。提前非常感谢可以提供的任何帮助。
大家新年快乐!
感谢@juanchopanza的帮助下,我为这个问题提出了一个可行的解决方案。
仍然不确定指针在上面发布的先前实现中的确切位置或方式失效,但现在通过使用索引来识别向量中的正确元素,然后返回该元素本身,而不是指向此位置的指针,我是安全的;)
t& operator [] (string s) {
bool nu = true;
for (auto& e : actual) // for each pair
if (e.first == s) // if exist
nu = false;
if (nu == true) { // if needs created
actual.push_back(pair <string, t>()); // create proper pair
actual.back().first = s; // assign key
lookup[s] = actual.size()-1; // assign proper index in map @ same key
}
return actual[lookup[s]].second; // return reference to value
}
此行暴露了错误
actual.push_back(pair <string, t>()); // create proper pair
这就是苦难的根源。
lookup[s] = &actual.back().second; // a pointer to an element in a vector.
当向量调整大小时会发生什么?为向量分配一个新数组,并将旧数组中的数据复制到新数组中,并解除分配旧数组。这将使指向旧数组的指针无效。
让我们稍微评估一下您的解决方案,您遍历向量以查看是否存在s
,这是 O(N),如果找到,您将在 O(log N) 的映射中进行lookup
。
我们希望使用索引而不是指针,因此您的地图对应该是
using mappair = std::pair<std::string, int>;
所以如果我们重写(未经测试的代码)
for (auto& e : actual) // for each pair
if (e.first == s) // if exist
nu = false;
if (nu == true) { // if needs created
actual.push_back(pair <string, t>()); // create proper pair
actual.back().first = s; // assign key
// create copy in map @ same key pointing to actual value
lookup[s] = &actual.back().second;
}
return *lookup[s]; // return reference to value
自
auto found = lookup.insert(mappair(s, -1));
if (found.second) { // true if new element
actual.emplace_back(mappair(s,t());
found->first.second = actual.size()-1;
}
return *found.first;
相关文章:
- 在子集化后将包含索引号的列表列表映射到标准索引序列
- Azure Kinect 使用正文索引映射裁剪正文
- 按字母顺序对C++问题中的子字符串索引进行分区
- C++ 中集合和映射中值的lower_bound索引
- 使用无序映射进行错误索引
- 查找数组的第一个和最后一个索引,其中 from 和 to 元素的顺序总和最大
- Rust 在索引时是否隐式创建映射条目,例如C++
- C/C++ Windows 或 Linux 将随机内存块映射成连续的顺序
- 编写一个递归功能,该功能采用数组并以相反顺序显示元素,而无需在末尾启动数组的索引
- C++静态初始化顺序:添加到映射中
- 为什么在将单词从文本文件C++到行进行多重映射时获得额外的索引值
- 创建按顺序索引的有序映射
- 将 [] 索引到无序映射时出现段错误
- 多重映射是否保证广告顺序与其初始值设定项中给出的元素顺序匹配
- 找到唯一向量的索引和逆映射
- 以std::字符串作为关键字,按字典顺序对一个无序映射进行排序
- 不能使用结构作为映射的索引
- 如何使用模板创建排序映射整数索引
- 获取元素在boost::multi_index_container的顺序索引中的位置
- vc++中相等键的多映射顺序