【问题标题】:std::set with unconsistent operator<std::set 与不一致的运算符<
【发布时间】:2015-07-21 08:43:32
【问题描述】:

我正在编写一个 C++ 算法来解决棋盘游戏。 解决方案基于以下几点:

enqueue initial board
while queue not empty:
    dequeue a board
    if board is solved:
        print solution
    else:
        for each possible board that can arise out of this one:
            add board to end of queue

由于我不想多次检查同一个板,我使用std::set&lt;Board&gt; 来跟踪检查过的板。

Board 类中定义bool operator&lt;(const Board&amp; rhs) const 以使std::set 正常工作。

如果我的比较函数不能确保板实例中的顺序,我的std::set 会发生什么?

例如:

a = Board()
b = Board()
c = Board()

a > b returns true
b > c returns true
a > c returns false

std::set 基于 Red-Black Tree 是否有可能多次插入同一个 Board?

【问题讨论】:

  • 如果 operator&lt; 不能作为适当的比较器工作 - 容器行为未定义且特定于实现
  • 由于程序未定义,任何事情都可能发生。
  • 要补充其他人所说的,如果您使用的是 Visual C++,调试运行时会检查这一点,如果您执行了与您发布的内容类似的操作,则调试运行时将失败并返回 assert()。因此,对于 Visual C++ 调试运行时,行为是“明确定义的”——您的程序将 assert() 并退出。
  • 我无法从您的回答中获得检查的内容和时间。你的意思是在std:set insert中抛出了一个断言?
  • @kuket15:正确,VC++ 在插入相对于与之比较的项目无序的元素时断言。请记住,Visual C++ 不会将它与 all 集合元素进行比较,即使是调试版本也会非常昂贵。

标签: c++ set stdset


【解决方案1】:

如果比较器不能正常工作,结构就不能正常工作。它可能会报告缺少项目。它可能无法插入某些东西。它可能会很快崩溃,或者它似乎适用于您的所有测试用例,然后在客户的机器上崩溃。

所有赌注都取消了。

【讨论】:

  • 你能序列化板子,即将它们变成字符串或字节序列吗?如果是这样,您可以比较序列化的表示。 (这确实需要一个唯一的序列化;即,如果一个特定的序列化取决于移动的历史,那么两个“相同”的棋盘实际上可能是不相等的。C++ 在这里不做假设)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 2013-11-23
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多