近几天在思考老师给出的问题:巡回置换算法的意义
我在网上找了很久这个问题的答案,发现只有实现过程而没有详细的解释,故来探究一番
一、实现
下面是c++实现的巡回置换算法:
#include <iostream>
using namespace std;
int main(){
int p[7] = { 4,7,3,1,2,5,6 };
int x, k;
k = 0;
while (k <= 6){
x = k + 1;
do {
cout << x << " ";
x = p[x - 1];
} while (x != k + 1);
cout << endl;
k++;
}
return 0;
}
当你自己跟随这个代码取走几次很容易就会发现:这个玩意就是俄罗斯套娃啊
不懂?int x = 0, nums[999],知道什么意思吧?nums[x]也知道什么意思吧(nums数组里面的第x个数字(注意是从0开始编号)),如果你明白上述意思了,那么应该就能理解nums[nums[x]]的含义了
=>nums数组里的第(nums[x]) 个数字
而我们已经知道了nums[x] 的意义 =>
代入可得 => nums数组里的第(nums数组里面的第x个数字)个数字
当然我们还可以套一层 =>nums[nums[nums[x]]]
乍一看,有一种递归的感觉,下面是递归的解决方式:
#include <iostream>
using namespace std;
int p[7] = { 4,7,3,1,2,5,6 };
int k = 0;
void fun(int x) {
if (k > 6)
return;
cout << x << " ";
if (x == k + 1) {
k++;x++;
cout << endl;
}
fun(p[x-1]);
}
int main(){
fun(p[0]);
return 0;
}
比循环容易清晰明了得多,所以说了这么久还是不知道它到底有什么用,别急,往下看。
二、实现
如果你看过谍战片的话,总是绕不过一个玩意——密码表
在现代加密有多重要相信不用我多说,那么多重加密就像巡回置换算法一样,简单来说就是对一个信息按密码表多次运算变成一堆乱码,有一件趣事可以了解一下:
言归正传:假如我们有一串字符I LOVE YOU,我们想对它进行加密,怎么办呢?
我们可以设计加密规则:比如所有字母往后推一位(如果是Z就变成A),那么结果就变成了J MPWF ZPV,这是最简单的加密方式,乍一看也不知道它的涵义,那么我们再往后推一位K NQXG AQW。有没有感觉像之前的nums?
I LOVE YOU => x J MPWF ZPV => nums[x] K NQXG AQW => nums[nums[x]]
这就是俄罗斯套娃,拆了一层又一层,说完了密码方面,我们还有其他用途 => 排序方法里面赫赫有名的——计数排序。
现在我们有几个球,编号从左至右分别为 1 2 5 3 4 5 3 0 现在要求从小到大排序,当然,我们可以用家喻户晓的冒泡排序,但是这样速度并不快,因为它要比较8*8 = 64次,那么计数排序是怎么排序的呢?
我们可以拿五个箱子来,给他从左至右编上号0 1 2 3 4 5,然后把小球对号入座,放进去
仔细想想,如果我们把小球命名为x,箱子命名为nums,那么上述操作其实就是 x 放在 nums中 => nums[x],当然,我们甚至还可以再搞一堆同样的盒子再把旧盒子放进新盒子里,这样就成了把nums[x] 放在 nums中 => nums[nums[x]]
暂时就只想到这么多,以后可能会更新。