【问题标题】:Most efficient way to move row/column in 2D std::vector在 2D std::vector 中移动行/列的最有效方法
【发布时间】:2013-04-19 02:45:03
【问题描述】:

我正在用 C++ 创建游戏应用程序。我将地图表示为Tile 对象的二维std::vector

我需要在玩家移动时更新该地图。从服务器应用程序中,我得到带有全局地图新部分的行或列,它应该放在本地客户端的地图中,例如:

在图 1 中,玩家移动之前有一张本地地图。顶行用对象 1 填充,中心用 2 填充,底部用 0 填充。现在当玩家向上移动时,我得到新的顶行填充对象 3,所有其他对象都应该向下,并且之前的底行应该消失。

我可以通过在for 循环中移动所需的对象来做到这一点,但我在想标准库中是否已经存在某种算法,或者许多有效的方法都喜欢实现这种修改。

编辑:

抱歉,我没有意识到对行和列执行此操作会有区别,但确实有。所以我也编辑了我的标题,因为我有时也需要为专栏做。

【问题讨论】:

  • 所以你有一个std::vector<std::vector<Tile>>?哪个维度代表您的列,哪个代表行?这很重要,因为如果第二维表示行,则很容易实现这个“向上”命令。你可以交换第 1 行和第 2 行,然后交换第 1 行和第 3 行,然后替换第 1 行。交换可以通过对向量的指针进行三次异或来有效地实现,每次交换产生 3 个处理器指令。

标签: c++ performance algorithm vector multidimensional-array


【解决方案1】:

您可能想要实现一个迭代器并且根本不移动向量的元素。只需为顶行的索引定义一个变量(在屏幕上),然后使用模运算符遍历所有行(因此只有 000 行应该被 333 覆盖,顶行索引将为 2 而不是0)。这个算法是高效的(只需要尽可能多的内存写入),并且可以用于向任何方向滚动:

  • 向上移动:递减顶行索引(mod 行号),改变最后一行
  • 向下移动:增加顶行索引(mod 行号),更改第一行
  • 向左移动:减少左侧列索引(mod col 编号),更改最后一个列
  • 向右移动:增加左列索引(mod col 编号),更改第一个列。

【讨论】:

  • 这听起来对我来说是一个非常好的解决方案,但我有一个可能很愚蠢的问题 - 你写道我应该实现一个迭代器,但在哪里实现它?
  • @dziwna:只需将您的矩阵包装在一个还包含行/列索引的类中,并提供考虑这些索引的访问器(以及滚动方法,当您使用它时) .
【解决方案2】:

当您需要在两个末端快速插入/擦除时,会立即想到两个标准容器:std::dequestd::list。但是,它们有其特定的要求和限制。

如果您被向量困住,您可以利用 C++11 移动语义,这将允许您有效地移动对象而不是复制它们,或者正如 @WebMonster 提到的,您可以在您的完全无需移动/复制的缓冲区。

鉴于您的要求,并假设它们是完整的,我可能会选择@WebMonster 的最有效的解决方案。 编辑:现在您的要求已经改变,并且您还需要在列上滚动,他的解决方案“循环索引”绝对是要走的路。

【讨论】:

    【解决方案3】:

    您可以使用专门用于向量的 std::swap 并且效率很高,因为它只需要对两个向量进行几次指针交换。此外,您可以使用 std::rotate,但我不确定它是否使用交换技术。

    不幸的是,只有当您有一个行向量并且您需要移动行,或者您有一个列向量并且您需要移动列时,这才有效。 看来要有效地完成这两个操作,您必须使用一些更复杂的数据结构。

    【讨论】:

      【解决方案4】:

      我会试试boost matrix

      【讨论】:

        【解决方案5】:

        一种可能的方法是使用:

        std::std::swap_ranges() 用于移动 2D 中已经存在的行 std::vector

        std::transform() 用于修改需要用新值替换的行。

        【讨论】:

          猜你喜欢
          • 2021-07-27
          • 1970-01-01
          • 1970-01-01
          • 2017-07-20
          • 1970-01-01
          • 2017-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多