我有一个关联数组,我存储键值对,我可以在其上执行交换操作:
swap(a, b) // a <-> b
{
temp = map.value(b);
map.value(b) = map.value(a);
map.value(a) = temp;
}
现在,给定一系列交换,我想知道我执行的下一次交换是否会导致关联数组进入以前的状态:
e.g。序列:
1 <-> 2
2 <-> 1
和
1 <-> 2
2 <-> 3
3 <-> 1
2 <-> 3
两者都什么都不做。
我希望能够通过查看交换序列本身来检测这一点。我猜这种问题有数学公式,但我似乎无法弄明白。
我发现第一个例子是一个循环而第二个有一个循环,所以“在有向图中检测循环”可能是解决方案的一部分,但是我不确定这将如何适合我正在寻找的算法。
算法也适用于交错的无关互换,最简单的例子是:
1 <-> 2
100 <-> 200
2 <-> 1
200 <-> 100
答案 0 :(得分:0)
这是permutations的应用(并不是图论的应用)。
由于这些是键值对,因此可能它们可能是稀疏的数字集,如上一个例子(1,2,100,200),甚至是字符串:
Dancer <-> Vixen
Prancer <-> Blitzen
Comet <-> Donner
Vixen <-> Rudolph
Prancer <-> Dasher
Comet <-> Cupid
Vixen <-> Dasher
Cupid <-> Donner
Vixen <-> Blitzen
Prancer <-> Dasher
Dancer <-> Rudolph
Prancer <-> Rudolph
Comet <-> Cupid
Prancer <-> Vixen
以及数字,我会做的是以下(至少有两种方法可以做到这一点):
然后:
一个。程序解决方案:
2A。按顺序在ML地图上执行交换。 3A。为了检查排列是否完整地保留了映射,验证ML [L [i]] = i对于0和N-1之间的每个整数i,其中N = L的长度。
B中。矩阵解决方案:
将每个交换表示为置换矩阵,使用列表L和映射ML从交换密钥转换 - &gt;整数索引。例如,Dancer&lt; - &gt; Vixen交换元素0和1,它由置换矩阵表示:
010000000
100000000
001000000
000100000
000010000
000001000
000000100
000000010
000000001
)并乘以置换矩阵。然后检查最后是否有单位矩阵。
“A”解决方案效率更高,但带有矩阵的“B”解决方案本质上更具数学性。