我从两天开始思考这个问题,但没有找到切实可行的决议:
我有一个二维数组,想要找到连接的最大数量的项目(水平和垂直,而不是对角线),但该组的项目不应该重复。
可能的群组示例:
--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处。
我认为上面描述的第一个找到元素的连接项的中间步骤是不必要的,但是现在我在这里和我的代码中这样做以使事情变得更清楚:)
答案 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个)。这里有五个例子。
----- ----- ----- ----- *----
----- ----- ----- ----- *----
----- ----- ----- ***-- ***--
----- ---*- --*-- *---- -----
***** ****- ****- *---- -----
现在我用这些掩码检查每个连接的组件。如果此位置上的所有五个项目都不同,则检查为真。掩码中检查的实际开始位置始终位于四个角中的一个角落。
这种方式比我尝试的每个算法都需要更少的内存和更少的计算,但是这个分辨率对于超过六个或七个项目是不可接受的,因为会有很多掩码。