假设您有一个字符串向量,用于将X存储在用户指定的位置。例如,用户可以键入“X 3”,您必须告诉他们是否可以在向量中的第3个位置插入X.这就是出现问题的地方......告诉用户插入是否有效。
因此,基本上,向量分配了2个数字,每次用户运行程序时都会更改。因此,假设矢量大小为10,分配给它的数字为3,2。这意味着必须有一个3 X的运行,至少一个空间和一个2 X的运行。所以,它看起来像这样:
X X X _ _ _ _ X X _
在这种情况下,如果用户在X所在的任何上述位置输入X,则这将是有效的移动。但是,用户也可以这样做:
_ _ _ _ X X X _ X X
这也是有效的。
我的问题是:如何设置一个系统来处理有效的用户输入的所有可能组合?
请记住,矢量大小可以是任何大小。这个问题实际上是picross拼图的一部分,万一有帮助!
答案 0 :(得分:1)
以下函数生成段之间空格的排列,当它不能再生成时返回false:
template <typename SpaceIter>
bool next(SpaceIter start, SpaceIter finish)
{
for (SpaceIter i = start; i != finish; ++i)
{
// Find the first non-minimised space.
if (*i)
{
SpaceIter j = i; ++j;
if (j == finish)
return false;
int s = *i; // Remember *i, in case i == start.
// Preserve the invariant: Σ(space[i])
// i != start i == start
// ---------- -----------
// Minimise current.
*i = 0; // Gain = -s overwritten
// Increment the next.
++*j; // Gain = 1 1
// Adjust the first.
*start = s - 1; // Gain = s - 1 -1
// -----------------------
// Nett = 0 0
return true;
}
}
return false;
}
请注意,此算法要求在末尾包含空格并在多余空间上工作 - 即,如果长度为S的空间位于任一端,则表示为S,但为S - 1如果它位于中间的某个地方,因为内部空间必须长度为1或更长。为了清楚起见,在此表示中,所有空格的最小值都为零。通过将第一个空格设置为N + 1 - Σ i = 0..N (长度 i + 1)和剩余的N + 1来初始化spaces
空格为0,其中N是序列的数量。
要完成这个故事,您需要测试任何给定的空格排列,以及长度数组是否与给定输入兼容。
一种简单的方法是在开始时将输入转换为位集。然后将每个空间排列与长度数组一起转换为位集并从输入位集减去。如果结果为空,则输入有效。
警告:我非常仔细地分析了上面的算法,但是我对代码的测试很少。这是我编写的一个相当粗糙的测试驱动程序,以防它有助于您自己的测试:
template <typename T, int N>
bool next(T (&spaces)[N])
{
return next(spaces, spaces + N);
}
const char* x(int n) { return "XXXXXXXXXX" + 10 - n; }
const char* s(int n) { return "----------" + 10 - n; }
int main(int argc, const char* argv[])
{
int spaces[] = { 4, 0, 0, 0 };
do
{
// I reverse the spaces to make segments shuffle left-to-right.
// This is a purely aesthetic thing. The order of permutations
// doesn't matter.
std::cout << s(spaces[3]) << x(2)
<< s(spaces[2] + 1) << x(1)
<< s(spaces[1] + 1) << x(1)
<< s(spaces[0])
<< "\n";
}
while (next(spaces));
}