将2d数组中的符号分为2组

时间:2019-01-08 23:44:41

标签: c++ arrays algorithm

我有以下问题。我有一个N*M 2d-array,充满了*o。现在,我想制作另一个相同大小的数组,以将所有*标记为12,因此基本上将它们分为2组,这样1's2's相邻。另外,如果*没有其他*作为邻居,则将其标记为3,例如:
* o * o
o o * *
o * * *
* * o o

成为这个:
3 0 1 0
0 0 2 1
0 2 1 2
2 1 0 0

我试图遍历所有单元格,当我找到一个*时,我放了一个1,它的邻居为2,依此类推。它以1开头,然后如果有很多邻居,它会很好地工作,但是如果遇到另一个没有标记邻居的*,我也不知道如何标记它,所以我只是在这里放一个1。但是它可能会与其他碰撞(例如,让我们可视化并将数字放入原始数字中):
o o 1 2
* * 2 o
o o * o
现在,我的代码将1标记为T [1] [0]星号,紧随其后的将变成2,这是不正确的。我不知道如何确定在这种情况下要放置1还是2。我试图同时将更多邻居放到下面,但是问题始终是相同的。

3 个答案:

答案 0 :(得分:4)

首先以棋盘形式用1和2填充输出数组:

1 2 1 2
2 1 2 1
1 2 1 2
2 1 2 1

然后在需要的地方放置0和3。为此,请查看输入数组的每个元素。如果元素是o,则将0放在输出数组中的同一位置。如果元素是*,请检查四个邻居。如果*都不是,则在输出数组中的该位置放置一个3

3 0 1 0
0 0 2 1
0 2 1 2
2 1 0 0

您实际上可以一次完成整个过程。如果输出数组的元素不应该是03,则可以在12之间进行选择,如下所示:如果行索引加上列索引是偶数,然后在输出数组中放入1,否则放入2

答案 1 :(得分:0)

您已经很好地确定了问题所在:给定的算法存在致命缺陷。

您必须继续标记连续的恒星组,交替使用12标签,直到用尽所有邻居。这不是一个简单的for row ... for col数据结构:它是一个格子图。

从图形的副本开始。

找到任何*。如果有邻居,请将其放在“ two_do”列表中,并用1标记原始位置。如果没有邻居,请用3进行标记。

对于“ two_do”列表中的每个节点... 用2标记节点。 将其所有邻居添加到“ one_do”列表中。

继续在“ two_do”和“ one_do”列表之间交替,直到不再有需要标记的邻居为止。

返回并找到另一个未编号的*。如果没有剩余,就可以了。

使用给定的网格,在左上角为(0,0),在右上角为(0,3):

* o * o
o o * *
o * * *
* * o o

在第一阶段,我们简单地将(0,0)标识为没有邻居的*

3 o * o
o o * *
o * * *
* * o o

接下来,我们在(0,2)找到*。用1标记,然后将唯一的邻居放在“ two_do”列表中:

3 o 1 o      (1, 2)
o o * *
o * * *
* * o o

现在,遍历该列表,并用2标记这些项(仅1),并将其(其)开放邻居显示在“ one_do”列表中。

  grid       two_do   one_do
3 o 1 o      (done)   (1, 3)
o o 2 *               (2, 2)
o * * *
* * o o

接下来,浏览“ one_do”列表,打开进入“ two_do_列表”的邻居:

  grid       two_do   one_do
3 o 1 o      (2, 3)   (done)
o o 2 1               (2, 2)
o * * *
* * o o

  grid       two_do   one_do
3 o 1 o      (2, 3)   (done)
o o 2 1      (2, 1)   (done)
o * 1 *
* * o o

继续执行此操作,直到我们用尽所有邻居为止:

  grid       two_do   one_do
3 o 1 o      (done)   (3, 1)
o o 2 1      (done)
o 2 1 2
* * o o

  grid       two_do   one_do
3 o 1 o      (3, 0)   (done)
o o 2 1
o 2 1 2
* 1 o o

  grid       two_do   one_do
3 o 1 o      (done)
o o 2 1
o 2 1 2
2 1 o o

您现在不在网格中的*个开放状态中,因此您已完成。

答案 2 :(得分:0)

只要您上次“更改了任何内容”,就将在矩形上进行一系列循环,然后再次循环。扫描完整个阵列后,发现没有任何变化,就完成了。

您需要一组坐标来记住要处理的内容,并需要一个工作队列来记住需要完成的事情。

每个循环迭代仅通过扫描即可找到第一个*。找到后,将其推入带有以下信息(x,y,t)的workQueue中,其中x,y是矩形中的坐标,t是将其设置为的目标值1,并将“ didSomething”设置为true。

1)从队列中删除第一个元素,将矩形中的x,y坐标设置为其“ t”字段的任何值。将某些变量“ DidSomething”设置为true。

2)对于具有*的x,y的每个邻居,如果这些坐标不在已经处理的集中,则将它们添加到工作队列中,将值t从1-> 2或2-> 1翻转,并将这些坐标添加到已经处理的队列中。

3)如果队列不为空,请循环回到步骤1

最终,您将覆盖所有相邻的单元并耗尽队列。此“填充”已完成,但是由于didSomething为true,因此您将再次扫描以查找任何剩余的*字符。如果找到任何内容,请跳回填充例程。

祝您好运,并在完成后发布您的代码。 :)