【发布时间】:2022-01-21 18:19:20
【问题描述】:
这个问题是一个一般的算法问题,但我用 C++ 编写它,因为它是我遇到这个问题的语言。 假设我有以下功能:
using Matrix = std::array<std::array<uint8_t, 3>, 3>;
void findOccurrences(std::vector<Matrix>& output, const std::vector<std::vector<uint8_t>>& pattern);
假设 pattern 是从 0 到 255 的特定数字模式,它可以放入我上面定义的 Matrix 中,并且鉴于 0 表示“空”插槽,我希望能够将所有可能出现的pattern 生成为Matrix。
例如,给定以下模式:
{
{ 1, 2 },
{ 3, 4 }
}
我想接收以下矩阵向量:
1 | 2 | 0
3 | 4 | 0
0 | 0 | 0
0 | 1 | 2
0 | 3 | 4
0 | 0 | 0
0 | 0 | 0
1 | 2 | 0
3 | 4 | 0
0 | 0 | 0
0 | 1 | 2
0 | 3 | 4
图案不一定是正方形,但我们假设它不大于Matrix 可以包含的大小。
我已经想到了一些解决这个问题的方法,最后得出了我认为最明显的方法,但我很难弄清楚整个事情的逻辑。
到目前为止,我拥有的是:
void findOccurrences(std::vector<Matrix>& output, const std::vector<std::vector<uint8_t>>& pattern)
{
Pattern curPattern = {0}; //temporary pattern, to store each time the current we work on
const size_t lineOpts = 3 - pattern.size() + 1; //amount of possible line combinations
for (size_t i = 0; i < lineOpts; i++) //for each possible combination
{
for (size_t j = 0; j < pattern.size(); j++) //for each line in pattern
{
const size_t lineInd = j + i; //index of line in curPattern
const auto& line = pattern[j]; //current line in input pattern
const size_t colOpts = 3 - line.size() + 1; //amount of possible column combinations for this line
for (size_t k = 0; k < colOpts; k++) //for each possible column combination
{
for (size_t l = 0; l < line.size(); l++) //for each column in line
{
const size_t colInd = l + k; //index of column in curPattern
//got stuck here
}
}
}
}
}
我在这里遇到的问题是,我想不出一种在不失去可能性的情况下继续该算法的方法。例如,从我之前给出的示例结果向量中仅获取选项 0 和 2。另外,这种方法似乎效率低下。
这是正确的方法吗?如果是这样,我错过了什么?
编辑:我们还假设pattern 不包含0,因为它标志着一个空槽。
【问题讨论】:
-
两个问题 1) 如果模式包含零怎么办?会被视为空位吗? 2)我还没有阅读你的代码。它会从左上角到右下角循环两次并复制模式吗?我错过了什么吗?
-
您可以对低效率做的一件事是使用其他东西(可能是向量和行大小)来表示您的模式。向量的向量通常效率较低(除非您经常使用移动构造函数重用子向量)。
-
@Nimrod 我们假设该模式不包含零。我已经编辑了这个问题。至于你的第二个问题,这基本上就是我想要做的。但我认为使用这种方法我们错过了一些可能性,还是我错了?
-
@Abel 我明白了。我实际上更多地指的是函数本身,而不是它的输入类型。但注意到了。