【问题标题】:hash tables and 2d vectors哈希表和二维向量
【发布时间】:2011-06-03 13:22:44
【问题描述】:

我想将一个二维向量逐行推入哈希表中,然后在哈希表中搜索一行(向量)并希望能够找到它。我想做类似的事情

#include <iostream>
#include <set>
#include <vector>
using namespace std;

int main(){

std::set < vector<int> > myset;

vector< vector<int> > v;

int k = 0;

for ( int i = 0; i < 5; i++ ) {
 v.push_back ( vector<int>() );

for ( int j = 0; j < 5; j++ )
 v[i].push_back ( k++ );
}

for ( int i = 0; i < 5; i++ ) {
  std::copy(v[i].begin(),v[i].end(),std::inserter(myset)); // This is not correct but what is the right way ?

// and also here, I want to search for a particular vector if it exists in the table. for ex. myset.find(v[2].begin(),v[2].end()); i.e if this vector exists in the hash table ?

}

  return 0;
}

我不确定如何在集合中插入和查找向量。因此,如果有人可以指导我,那将很有帮助。谢谢

更新:

当我意识到std::set 不是哈希表时,我决定使用unordered_map,但我应该如何在其中插入和查找元素:

#include <iostream>
#include <tr1/unordered_set>
#include <iterator>
#include <vector>
using namespace std;

typedef std::tr1::unordered_set < vector<int> > myset;

int main(){
myset c1;
vector< vector<int> > v;

int k = 0;

for ( int i = 0; i < 5; i++ ) {
 v.push_back ( vector<int>() );

for ( int j = 0; j < 5; j++ )
 v[i].push_back ( k++ );
}

for ( int i = 0; i < 5; i++ )  
 c1.insert(v[i].begin(),v[i].end()); // what is the right way? I want to insert vector by vector. Can I use back_inserter in some way to do this?

// how to find the vectors back?

  return 0;
}

【问题讨论】:

  • 我编辑了最后一行。即使对于此代码,我也会在插入器行中遇到错误。我该怎么办?
  • 我没有看到哈希表。你在说std::set吗?
  • STL 集内的 STL 向量内的 STL 向量。没有上下文,这似乎是糟糕的设计。如果你解释你试图解决的问题,你肯定会得到更好的建议。
  • std::set 不是哈希表。这将是 C++0x 标准草案中的 std::unordered_mapstd::unordered_set
  • 我明白了。我假设 std::set 是一个哈希表。我想要的只是在哈希表的每个桶中插入一个向量,然后在代码中搜索该向量。就像插入和查找元素一样。

标签: c++ vector hashtable unordered-set


【解决方案1】:

对于插入使用std::set::insert,ala

myset.insert(v.begin(), v.end());

查找,使用std::set::findala

std::set < vector<int> >::iterator it = myset.find(v[1]);

工作示例:

#include <iostream>
#include <set>
#include <vector>
using namespace std;

int main()
{
  typedef vector<int> int_v_t;
  typedef set<int_v_t> set_t;

  set_t myset;

  // this creates 5 items 
  typedef vector<int_v_t> vec_t;
  vec_t v(5);

  int k = 0;

  for(vec_t::iterator it(v.begin()), end(v.end()); it != end; ++it)
  {
   for (int j = 0; j < 5; j++)
    it->push_back(k++);
  }

  // this inserts an entry per vector into the set 
  myset.insert(v.begin(), v.end());

  // find a specific vector
  set_t::iterator it = myset.find(v[1]);

  if (it != myset.end()) cout << "found!" << endl; 

  return 0;
}

【讨论】:

  • @Sunil,上面的发现对于上面的代码是正确的吗? v[1] 指的是包含 5 个项目(5 到 9)的 vector&lt;int&gt;,并且 find 找到匹配向量。我会举一个完整的例子。
  • 哎呀,我把一些东西改成了 typedefs 并留下了错误的;,这是工作版本:ideone.com/MqttE
  • 是的,我做到了,我只是想看看为什么我的代码不能正常工作。
【解决方案2】:

使用std::copy 插入集合:

#include <algorithm>
#include <iterator>
#include <vector>

std::vector<int> v1;
// Fill in v1 here
std::vector<int> v2;
std::copy(v1.begin(), v1.end(), std::back_inserter<std::vector<int> >(v2));

您也可以使用std::vector 的赋值、插入或复制构造函数来做同样的事情。

在此示例中,您使用的是 std::set。集合没有查找方法。您只需遍历对每个项目执行操作的集合。如果您想使用哈希/键查找特定项目,您需要查看std::map 等数据结构。

【讨论】:

    【解决方案3】:
    for ( int i = 0; i < 5; i++ ) {
      std::copy(v[i].begin(),v[i].end(),std::inserter(myset)); // This is not correct but what is the right way ?
    }
    

    这是不正确的,因为您试图将向量向量中每个向量的整数复制到集合中。您的意图和集合的类型表明您希望将 5 个向量插入到集合中。然后,您只需执行此操作(无 for 循环):

    std::copy(v.begin(), v.end(), std::inserter(myset));
    

    【讨论】:

    • 所以如果我想跳过元素,我会怎么做。比如说我想做 i+=2 ?
    • 使用 for 循环代替 std::copy。