在二维数组中查找连接的不同元素

时间:2013-02-18 11:04:45

标签: arrays 2d

我从两天开始思考这个问题,但没有找到切实可行的决议:

我有一个二维数组,想要找到连接的最大数量的项目(水平和垂直,而不是对角线),但该组的项目不应该重复。

可能的群组示例:

--FG- or -F--- or -----
--E--    -E---    ---AF
-BC--    CBD--    ----B
-AD--    -A---    --CDE

这是我的问题的简化视图,因为在“现实”中,数组是6x9,并且有三种不同类型的“元素”(比如数字,字母和符号),每30个不同的可能项目和一个空白( - )元素。在第一遍中,我检查每个位置并找到相同元素的所有连接项。使用递归函数相对容易实现,字段0,0位于左下角(另一个简化视图):

12AB-1-     The check for    -AB----  
23CD23-     position 2:0     -CD----
2*CE55-     ("C") would      --CE---
#2E2*AA     result in        --E----
#$A23BC     this:            --A----
$$F1+*E                      --F----
21C31*2                      --C----

检查位置2:0“C”将产生一个包含10个连接的“字母”项目的数组。现在,我在这个新数组中搜索最大数量的连接项,这些项是不同的,因此新组中不是两个重复的项。对于位置2:0,这将导致最多4个连接的不同项目,因为如果不触摸组中已有的项目(此处为另一个C),则无法到达另一个项目。

对于我的问题,检测最大值就足够了。 10个项目组中有6个不同的连接项目。

以上示例的可能组(当我检查位置2:1“F”时):

--B----
--D----
--C----
--E----
--A----
--F----
-------

我没有找到能够做到这一点的算法,就像我用来查找数组中相同元素的所有项的简单递归函数一样。它看起来要复杂得多。

例如,算法还必须识别它不会将位置3:4的E添加到组中,而将E添加到位置2:3处。

我认为上面描述的第一个找到元素的连接项的中间步骤是不必要的,但是现在我在这里和我的代码中这样做以使事情变得更清楚:)

2 个答案:

答案 0 :(得分:0)

这是一个DFS问题。算法应该是;

对于每个连接的组件,请使用dfs启动map。这是一个伪代码:

 void dfs(position pos, map<char, bool> m, int number) {

    //if the element is seen before, quit 
    if(m[array2d[pos] == true)
        return;

    //it is seen now
    m[array2d[pos]] = true;

    //update max value
    maxValue = max(maxValue, number);

    //go to each neighbor
    foreach(neighbor of pos) {
         dfs(neighbor, m, number+1); 
    }

    //unlock the position
    m[array2d[pos]] = false;
 }

我相信你应该从数组中的每个位置开始dfs

答案 1 :(得分:0)

因为我尝试的所有算法都不起作用或者会使用大的递归堆栈,所以我采用了另一种方式:

为了我的目的,它足以检查最大值。 5个连接在一组元素中的不同项目。我为5个项目制作了所有可能组合的面具(大约60个)。这里有五个例子。

----- ----- ----- ----- *----
----- ----- ----- ----- *----
----- ----- ----- ***-- ***--
----- ---*- --*-- *---- -----
***** ****- ****- *---- ----- 

现在我用这些掩码检查每个连接的组件。如果此位置上的所有五个项目都不同,则检查为真。掩码中检查的实际开始位置始终位于四个角中的一个角落。

这种方式比我尝试的每个算法都需要更少的内存和更少的计算,但是这个分辨率对于超过六个或七个项目是不可接受的,因为会有很多掩码。