完美洗牌算法的多种实现
来源:互联网 发布:三星手机套淘宝 编辑:程序博客网 时间:2024/05/10 01:40
非常喜欢看“v_JULY_v”大神的博客,可以说受益颇多。大神博客首页:http://blog.csdn.net/v_july_v?viewmode=contents。
昨天看了“程序员编程艺术第三十四~三十五章:格子取数问题,完美洗牌算法”,稍微实现了下文章提到的几种关于洗牌的算法,记录在此。
关于“完美洗牌”的理论,我在这不多讲了,请看上面的链接,这里只给出我自己实现的代码。
1.位置置换perfect_shuffle1算法
#define NUM 9char * pa[9] = {NULL,"a1", "a2", "a3", "a4","b1", "b2", "b3", "b4"};void display_strings(char * pa[], int n){int i;for(i = 1; i < n; ++i)cout << pa[i] <<" ";cout << endl;}void perfect_shuffle1(char * pa[], const int n){int i = 0;char * pTmp[NUM];for (i = 1; i < n; ++i){pTmp[2 * i % n] = pa[i];}for (i = 1; i < n; ++i){pa[i] = pTmp[i];}}int main(){display_strings(pa, 9);perfect_shuffle1(pa, 9);display_strings(pa, 9);return 0;}
实验结果:
2.分而治之perfect_shuffle2算法
#define NUM 9char * pa[9] = {NULL,"a1", "a2", "a3", "a4","b1", "b2", "b3", "b4"};char * pb[11] = {NULL,"a1", "a2", "a3", "a4", "a5","b1", "b2", "b3", "b4", "b5"};void display_strings(char * pa[], int n){int i;for(i = 1; i < n; ++i)cout << pa[i] <<" ";cout << endl;}void perfect_shuffle2(char * pa[], int start, int end){int n = (end - start + 1) / 2;int i = 0, j = 0;char * tmp;if (n == 1){return;}if (n & 0x01){tmp = pa[n];for (i = n; i <= 2 * n - 2 ; i++){pa[i] = pa[i + 1];}pa[2 * n - 1] = tmp;n--;}for (i = n / 2 + 1, j = 1; i <= n; ++i, j++){tmp = pa[i + start - 1]; pa[i + start - 1] = pa[j + n + start - 1]; pa[j + n + start - 1] = tmp;}perfect_shuffle2(pa , 1, n);perfect_shuffle2(pa , n + 1, 2 * n);}int main(){cout << "---------------------------------\n";display_strings(pa, 9);perfect_shuffle2(pa, 1, 8);display_strings(pa, 9);cout << "---------------------------------\n";cout << "\n";cout << "---------------------------------\n";display_strings(pb, 11);perfect_shuffle2(pb, 1, 10);display_strings(pb, 11);cout << "---------------------------------\n";return 0;}
3.完美洗牌算法perfect_shuffle3---走圈法
1)递归实现,有点“分而治之”的味道
#define NUM 9char * pa[9] = {NULL,"a1", "a2", "a3", "a4","b1", "b2", "b3", "b4"};char * pb[11] = {NULL,"a1", "a2", "a3", "a4", "a5","b1", "b2", "b3", "b4", "b5"};void display_strings(char * pa[], int n){int i;for(i = 1; i < n; ++i)cout << pa[i] <<" ";cout << endl;}void cycle(char * pa[], int start, int mod){char * last = pa[start], * tmp;int i;for (i = 2 * start % mod ; i != start; i = 2 * i % mod){tmp = pa[i];pa[i] = last;last = tmp;}pa[start] = tmp;}void rotate_right(char * a[], int from, int to){char * tmp;for (; from < to; ++from, --to){tmp = a[from]; a[from] = a[to]; a[to] = tmp;}}void perfect_shuffle3(char * a[], const int n){int m, k, i, order;if(n == 0)return;for (k = 0, order = 1; order <= 2 * n + 1; ){++k;order *= 3;}k--;m = (order / 3 - 1) / 2;rotate_right(a, m + 1, n);rotate_right(a, n + 1, n + m);rotate_right(a, m + 1, n + m);for (i = 0, order = 1; i < k; ++i){cycle(a, order, 2 * m + 1);order *= 3;}perfect_shuffle3(a + 2 * m, n - m);}int main(){cout << "---------------------------------\n";display_strings(pa, 9);perfect_shuffle3(pa, 4);display_strings(pa, 9);cout << "---------------------------------\n";cout << "\n";cout << "---------------------------------\n";display_strings(pb, 11);perfect_shuffle3(pb, 5);display_strings(pb, 11);cout << "---------------------------------\n";return 0;}
2)看了“v_JULY_v”的代码,感觉完全没必要用到递归,故修改了源代码,得到“迭代”版本。
#define NUM 9char * pa[9] = {NULL,"a1", "a2", "a3", "a4","b1", "b2", "b3", "b4"};char * pb[11] = {NULL,"a1", "a2", "a3", "a4", "a5","b1", "b2", "b3", "b4", "b5"};void display_strings(char * pa[], int n){int i;for(i = 1; i < n; ++i)cout << pa[i] <<" ";cout << endl;}void cycle(char * pa[], int start, int mod){char * last = pa[start], * tmp;int i;for (i = 2 * start % mod ; i != start; i = 2 * i % mod){tmp = pa[i];pa[i] = last;last = tmp;}pa[start] = tmp;}void rotate_right(char * a[], int from, int to){char * tmp;for (; from < to; ++from, --to){tmp = a[from]; a[from] = a[to]; a[to] = tmp;}}void perfect_shuffle4(char * a[], int n){int m, k, i, order;while (n > 0){for (k = 0, order = 1; order <= 2 * n + 1; ){++k;order *= 3;}k--;m = (order / 3 - 1) / 2;rotate_right(a, m + 1, n);rotate_right(a, n + 1, n + m);rotate_right(a, m + 1, n + m);for (i = 0, order = 1; i < k; ++i){cycle(a, order, 2 * m + 1);order *= 3;}a += 2 * m;n -= m;}}int main(){cout << "---------------------------------\n";display_strings(pa, 9);perfect_shuffle4(pa, 4);display_strings(pa, 9);cout << "---------------------------------\n";cout << "\n";cout << "---------------------------------\n";display_strings(pb, 11);perfect_shuffle4(pb, 5);display_strings(pb, 11);cout << "---------------------------------\n";return 0;}
结束!!!
- 完美洗牌算法的多种实现
- 洗牌算法多种形式
- 完美洗牌算法
- 完美洗牌算法学习
- 完美洗牌算法
- 完美洗牌算法学习
- 完美洗牌算法
- 完美洗牌算法
- 105完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法学习
- 完美洗牌算法
- 完美洗牌算法
- 完美洗牌算法
- 设计原则
- poj 1664
- pl/sql编译无效对象
- uCOS-Ⅱ的O(1)调度算法
- 在 Windows 8 上安装 .NET Framework 3.5
- 完美洗牌算法的多种实现
- UVA - 10913 Walking on a Grid
- Handle机制详解
- paip.提升用户体验---c++ QPushButton按钮控件透明以及不规则按钮以及 鼠标越过动态设置
- OCP-1Z0-052-V8.02-33题
- android利用代码构建UI
- Effective C++ 第二版 15) operator=返回值 16) operator=赋值
- 强烈不推荐使用flipper实现左右滑动动画显示结果
- 中国天气网api(json格式)