具有自定义键类型的std :: unordered_set允许插入重复键

时间:2018-06-11 04:55:02

标签: c++11 unordered-set

代码是一个简单易用的第一个搜索测试代码。

我有std::unordered_set个自定义密钥。

但是它可以插入两个重复的键!

使用find函数保护插入条件。

insert函数也会像屏幕截图一样返回true

duplication inserted

以下是使用Visual Studio 15.7.3

运行的可重现代码

您可以在C ++ Shell上使用链接http://cpp.sh/4iq27

进行尝试
#include <iostream>
#include <unordered_set>
#include <queue>
#include <cmath>

using namespace std;

long kth(int k) {
  struct Point {
    int x;
    int y;
    int z;
  };

  auto calc = [&](const Point &p) -> size_t {
    return pow(3, p.x) * pow(5, p.y) * pow(7, p.z);
  };

  // min heap
  auto greater_cmp = [&](const Point &l, const Point &r) { return calc(l) > calc(r); };
  priority_queue<Point, vector<Point>, decltype(greater_cmp)> pq(greater_cmp);

  // hash set
  auto point_hash = [&](const Point &p) { return p.x * k * k + p.y * k + p.z; };
  auto point_equal = [&](const Point &l, const Point &r) { return l.x == r.x && l.y == r.y && l.z == r.z; };
  unordered_set<Point, decltype(point_hash), decltype(point_equal)> visited(k, point_hash, point_equal);

  // init
  pq.push({ 1, 1, 1 });
  visited.insert({ 1, 1, 1 });

  auto push = [&](const Point &p) {
    if (visited.find({ p.x, p.y, p.z }) == visited.end()) {
      pq.push({ p.x, p.y, p.z });
      auto res = visited.insert({ p.x, p.y, p.z });
      cout << "insert {" << p.x << ", " << p.y << ", " << p.z << "} " << res.second << endl;
    }
  };

  // expand and generate
  while (k-- != 1) {
    // expand
    auto p = pq.top();
    pq.pop();

    // generate
    push({ p.x + 1, p.y, p.z });
    push({ p.x, p.y + 1, p.z });
    push({ p.x, p.y, p.z + 1 });
  }

  return calc(pq.top());
}

int main() {
  kth(7);
}

0 个答案:

没有答案