- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经创建了一个带有基本实现的简单 HashMap (unordered_map)。现在,我想创建一个派生自 std::iterator 的简单自定义前向迭代器。但是,我无法弄清楚迭代器的第一个和第二个成员的实现,例如 unordered_map 的迭代器。有人能帮助我吗 ?为简单起见,假设我的 HashMap 有固定的 10 个桶,并且假设元素是整数类型,只使用简单的模数来获取索引。下面是我的 HashMap 和迭代器的实现。
#include <iostream>
#include <iterator>
#include <utility>
#include <cassert>
template<typename K, typename V>
class Node
{
public:
K key;
V val;
Node *next;
Node(K k, V v)
{
key = k; val = v; next = nullptr;
}
};
template<typename K, typename V>
class Element
{
public:
int count;
Node<K, V> *head;
Node<K, V> *tail;
Element *next;
Element()
{
count = 0;
head = tail = nullptr;
next = nullptr;
}
};
template<typename K, typename V>
class ForwardIterator : public std::iterator<std::forward_iterator_tag, std::pair<K, V>>
{
Node<K, V> *itr;
Element<K, V> *el;
public:
explicit ForwardIterator(Node<K, V> *i, Element<K, V> *e) : itr(i), el(e) {}
ForwardIterator() : itr(nullptr), el(nullptr) {}
void swap(ForwardIterator& other)
{
std::swap(itr, other.itr);
std::swap(el, other.el);
}
ForwardIterator& operator++()
{
assert(itr != nullptr && "Out of bounds");
if(itr->next == nullptr) // last node in the current index
{
while(el->next != nullptr)
{
el = el->next;
if(el->head != nullptr) // if there is atleast one node at the current index
{
itr = el->head;
break;
}
else
itr = nullptr;
}
}
else
itr = itr->next;
return *this;
}
ForwardIterator operator++(int)
{
assert(itr != nullptr && "Out of bounds");
ForwardIterator tmp(*this);
if(itr->next == nullptr) // last node in the current index
{
while(el->next != nullptr)
{
el = el->next;
if(el->head != nullptr) // if there is atleast one node at the current index
{
itr = el->head;
break;
}
else
itr = nullptr;
}
}
else
itr = itr->next;
return tmp;
}
template<typename key, typename value>
bool operator==(const ForwardIterator<key, value>& rhs) const
{
return itr == rhs.itr && el == rhs.el;
}
template<typename key, typename value>
bool operator!=(const ForwardIterator<key, value>& rhs) const
{
return itr != rhs.itr || el != rhs.el;
}
std::pair<K, V>& operator* () const
{
assert(itr != nullptr && "Out of bounds");
return std::pair<K, V>(itr->key, itr->val);
}
std::pair<K, V>& operator-> () const
{
assert(itr != nullptr && "Out of bounds");
return std::pair<K, V>(itr->key, itr->val);
}
};
template<typename K, typename V>
class MyHashMap
{
private:
Element<K, V>* arr[10];
int size;
public:
typedef ForwardIterator<K, V> myIt;
typedef ForwardIterator<const K, const V> cMyIt;
MyHashMap()
{
size = 0;
arr[0] = new Element<K, V>();
for(int i=1; i<10; ++i)
{
arr[i] = new Element<K, V>();
arr[i-1]->next = arr[i];
}
}
myIt begin()
{
if(size == 0)
{
myIt m(nullptr, nullptr);
return m;
}
else
{
Element<K, V> *temp = arr[0];
while(temp->head == nullptr)
temp = temp->next;
myIt m(temp->head, temp);
return m;
}
}
myIt end()
{
myIt m(nullptr, nullptr);
return m;
}
std::pair<myIt, bool> insert(std::pair<K, V>& p)
{
int index = p.first%10;
if(arr[index]->head == nullptr)
{
arr[index]->head = new Node<K, V>(p.first, p.second);
arr[index]->tail = arr[index]->head;
++(arr[index]->count);
}
else
{
Node<K, V> *temp = new Node<K, V>(p.first, p.second);
arr[index]->tail->next = temp;
arr[index]->tail = temp;
++(arr[index]->count);
}
++size;
myIt m(arr[index]->tail, arr[index]);
return std::pair<myIt, bool>(m, true);
}
myIt find(K k)
{
int index = k%10;
Node<K, V> *temp = arr[index]->head;
while(temp != nullptr)
{
if(temp->key == k)
{
myIt m(temp, arr[index]);
return m;
}
else
temp = temp->next;
}
return end();
}
int remove(K k)
{
int index = k%10;
Node<K, V> *temp = arr[index]->head;
Node<K, V> *t2 = temp;
while(temp != nullptr)
{
if(temp->key == k)
{
if(arr[index]->count == 1)
{
delete temp;
arr[index]->head = arr[index]->tail = nullptr;
}
else if(arr[index]->head == temp)
{
arr[index]->head = arr[index]->head->next;
delete temp;
}
else if(arr[index]->tail == temp)
{
delete temp;
t2->next = nullptr;
arr[index]->tail = t2;
}
else
{
t2->next = temp->next;
delete temp;
}
--(arr[index]->count);
--size;
return 1;
}
else
{
t2 = temp;
temp = temp->next;
}
}
return 0;
}
V &operator[](K k)
{
int index = k%10;
Node<K, V> *temp = arr[index]->head;
while(temp != nullptr)
{
if(temp->key == k)
return temp->value;
else
temp = temp->next;
}
exit(0);
}
};
现在,下面是我的主要部分。
int main()
{
MyHashMap<int, int> mhm;
mhm.insert(std::pair<int, int>(1,1));
mhm.insert(std::pair<int, int>(2,2));
MyHashMap<int, int>::myIt it = mhm.begin();
//std::cout << it->first << " " << it->second << std::endl ->this line doesn't compile
}
编辑:上面提到的代码片段恢复到有问题的原始状态。 @"r3mus n0x"的回答非常清楚地总结了这个问题,@Evg 在评论中也指出了这个问题。按照建议进行更改后,它按预期工作。感谢大家的帮助。
最佳答案
->
运算符有两个问题:
std::pair<K, V>& operator-> () const
{
assert(itr != nullptr & "Out of bounds");
return std::pair<K, V>(itr->key, itr->value);
}
->
运算符应该返回一个指针,而不是一个引用。*
运算符相同的问题)。您当前的迭代器实现生成 元素而不是指向它们。这在某些情况下是可以接受的,但您将无法实现 ->
运算符,因为它应该返回一个指向现有值的指针,而不是临时值。
解决这个问题的最简单方法是在 map 节点中实际存储一个对
:
template<typename K, typename V>
class Node
{
public:
std::pair<K, V> value;
}
然后像这样实现您的 ->
运算符:
std::pair<K, V>* operator-> () const
{
assert(itr != nullptr & "Out of bounds");
return &itr->value;
}
关于c++ - 创建自定义迭代器时如何获取 std::pair 的第一个和第二个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52913329/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!