【问题标题】:Data structure for a crossword puzzle grid?填字游戏网格的数据结构?
【发布时间】:2021-12-03 20:53:04
【问题描述】:

我想用 C++ 设计一个填字游戏编辑器。它是一个由块组成的网格,每个块包含一个字母(或在两个单词之间为黑色),可能是一个数字和一条粗或细的边界线。 因此,块是它们的容器类。网格是块的容器。但是我将如何构建网格?

  1. 原始二维数组:Block grid[row][column]?
  2. 向量的向量:vector<vector<Block>>?
  3. 两个向量,一个用于行,一个用于列:vector<Block> row; vector<Block> column?
  4. 一个映射,其中键是行/列对,值是块:map<int[2], Block>?

【问题讨论】:

  • 如果网格的大小是编译时间常数,我更喜欢 std::array
  • 这确实是基于意见的答案,也取决于上下文。如果大小是固定的,使用数组,如果大小可以改变,使用向量。地图在这里太过分了。
  • 解决方案 1. 只有在编译时知道 rowcolumn 时才有效。我不明白解决方案 3. 如何工作。解决方案 4. 似乎过于复杂,少说。
  • @Damien:向量中序列中一行中的所有块,对于另一个向量,列中的所有块都相同。

标签: c++ crossword


【解决方案1】:

默认情况下,纯静态/动态数组(或它们的包装器)是最可取的:它们对程序员(随机访问 API 等)和处理器(内存局部性等)来说都是最舒适的。

数组/向量中最容易实现的Block 布局是[first row Blocks..., second row Blocks..., etc] - 一个充当二维数组的一维数组。它可以像crossword[x + y * crossword.width()] 那样被索引,这并不漂亮,所以你可能想要使用库/自写的包装器和像crossword(x, y) 这样的API,它在下面执行xy-to-i-index 转换引擎盖。

可能是这样的:

class Crossword {
    std::vector<Block> raw;
    size_t length{}; // can't name it "width" because there's a "width()" member function below

public:
    Crossword() {}
    Crossword(size_t x, size_t y): raw(x * y), length{x} {}
    Crossword(Crossword&& other) noexcept { *this = std::move(other); }
    Crossword& operator=(Crossword&& other) noexcept {
        std::swap(raw, other.raw);
        std::swap(length, other.length);
        return *this;
    }

    auto size() const { return raw.size(); }
    auto width() const { return length; }
    auto height() const { return size() / length; }
    auto& operator()(size_t x, size_t y) const { return raw[x + y * length]; }
    auto& operator()(size_t x, size_t y) { return raw[x + y * length]; }
};

【讨论】:

    猜你喜欢
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2011-06-30
    • 2022-12-10
    • 1970-01-01
    • 2021-03-21
    相关资源
    最近更新 更多